Ответ 1
Вы хотели бы объединить шаги аутентификации и запроса ресурсов в один запрос. Это происходит не только быстрее, но и безопаснее, чем ваша реализация. Рассмотрим следующий сценарий:
- Пользователь аутентифицируется на сервере. Результат - успех.
- Идентификация изменена. (например, пользователь меняет пароль, администратор решает заблокировать учетную запись пользователя и т.д.).
- Пользователь делает запрос с использованием sessionID в шаге 1.
Чтобы гарантировать, что пользователю не предоставлен доступ к ресурсу, вы должны аутентифицировать пользователя именно на шаге 3. Но это не имеет смысла, вы уже аутентифицировали этого пользователя ранее на шаге 1..
HTTP, в основном, предназначен именно для этого. Существуют различные способы передачи информации аутентификации вместе с запросом, например:
- Введите информацию об аутентификации в контент (глупо, но работает)
- Включить аутентификацию в URL-адрес, например. example.com/pic/123?sessionID=abc (лучше, но делает ваш URL уродливым и длинным)
- Сохранять информацию о сеансе в файле cookie (лучше, но что, если клиент не поддерживает cookie?) Что означает истечение срока действия cookie?)
- Аутентификация HTTP-заголовка (мои лучшие личные рекомендации)
У самого HTTP есть заголовок аутентификации, который должен быть совместим с "базовой аутентификацией" (он определенно определен, посмотрите, если вам интересно). Но вы можете реализовать свой собственный пользовательский заголовок.
Любой поиск в кэше должен быть медленным (по сравнению с вычислением), поэтому вы должны полностью исключить кеш для части аутентификации. Ваш сервер должен быть без гражданства; то есть не отслеживать сеансы входа в систему. Откуда вы знаете, действительно ли SessionID? Поместите на него временную метку. И чтобы другие не подделывали sessionID, подпишите его также.
Итак, ваш HTTP-запрос будет выглядеть примерно так (псевдокод):
var request = new HttpRequest();
request.url = "example.com/pic/123";
request.Headers["CustomAuth"] = "id=abc&t=123456789&s=01de45890a";
Внедрите свой собственный метод подписи, похожий на хеш-функцию (вы можете использовать HMAC) и надежно удерживайте ключ на сервере. Если подпись соответствует, вы знаете, что подписали это ранее при входе в систему, и это должно быть с вашего сервера. Временная метка помогает определить время окончания сеанса, а также защищает от атак с помощью повтора.
Теперь на вашем сервере сделайте что-то вроде этого:
public void Get(){
var authHeader = Request.Headers["CustomAuth"];
if(!validate(authHeader)){
Response.StatusCode = 404;
Response.End();
}else{
//something else
}
}
Если вам нужно выполнить авторизацию login + session authenticate + resource request в одном запросе, тогда для проверки подлинности всего 2 способа. Пользователи могут либо указать комбинацию имени пользователя/пароля, либо ключ сеанса. Подумайте об этом сценарии, который исходит из API, над которым я работал:
- пользовательский регистратор с именем пользователя/паролем Сервер
- отвечает на успех/неудачу регистрации (например, имя пользователя уже выполнено)
- Если это было успешно, теперь пользователь вступает в систему с именем пользователя/паролем combo
- сервер возвращает токен сеанса
Не было бы проще (и быстрее), если мы сделаем так:
- пользовательский регистратор с именем пользователя/паролем
- Если это успех, ответьте "reg success" и "sessionToken = xxxxxx". если это ошибка, ответьте "reg failure".
Надеюсь, это даст вам некоторую идею.