В настоящее время я работаю над библиотекой REST для .net, и мне хотелось бы услышать некоторые мнения о моей открытой точке зрения: REST и аутентификация.
Вот пример интерфейса RESTful, используемого с библиотекой:
[RestRoot("/user")]
public interface IUserInterface
{
[RestPut("/")]
void Add(User user);
[RestGet("/")]
int[] List();
[RestGet("/get/{id}")]
User Get(int id);
[RestDelete("/delete/{id}")]
void Delete(int id);
}
Серверный код затем просто реализует интерфейс, и клиенты могут получить тот же интерфейс через фабрику. Или, если клиент не использует библиотеку, также работает стандартный HTTP-запрос.
Я знаю, что существуют основные способы использования HTTP Basic Auth или отправки токена на запросы, требующие аутентифицированных пользователей.
Первый метод (HTTP Basic Auth) имеет следующие проблемы (частично относящиеся к веб-браузеру):
- Пароль передается с каждым запросом - даже с SSL это вызывает «плохое предчувствие».
- Поскольку пароль передается с заголовком запроса, локальному злоумышленнику будет легко просмотреть переданные заголовки, чтобы получить пароль.
- Пароль доступен в памяти браузера.
- Нет стандартного способа истечения срока действия пользовательских "сессий".
- Вход в систему с помощью браузера прерывает внешний вид страницы.
Проблемы для второго метода более сфокусированы на реализации и использовании библиотеки:
- Каждый URI запроса, который требует аутентификации, должен иметь параметр для токена, который просто очень повторяется.
- Нужно написать намного больше кода, если каждая реализация метода должна проверить, является ли токен действительным.
- Интерфейс станет менее специфичным, например,
[RestGet("/get/{id}")]
против [RestGet("/get/{id}/{token}")]
.
- Где поставить токен: в конце URI? после рута? где-то еще?
Моя идея состояла в том, чтобы передать токен в качестве параметра URL-адресу, например http:/server/user/get/1234?token=token_id
.
Другой возможностью было бы отправить параметр в виде заголовка HTTP, но это, я думаю, усложнило бы использование с простыми клиентами HTTP.
Маркер будет передаваться клиенту в виде настраиваемого HTTP-заголовка ("X-Session-Id") при каждом запросе.
Это тогда может быть полностью абстрагировано от интерфейса, и любая реализация, нуждающаяся в аутентификации, может просто спросить, к какому пользователю принадлежит токен (если дан).
Как вы думаете, это слишком сильно нарушит REST или у вас есть идеи получше?