Ошибка входа в систему RESTful: возврат 401 или настраиваемый ответ

103

Это концептуальный вопрос.

У меня есть клиентское (мобильное) приложение, которое должно поддерживать действие входа в систему для веб-службы RESTful. Поскольку веб-служба является RESTful, это означает, что клиент принимает имя пользователя / пароль от пользователя, проверяет это имя пользователя / пароль с помощью службы, а затем просто не забывает отправлять это имя пользователя / пароль со всеми последующими запросами.

Все остальные ответы в этой веб-службе предоставляются в формате JSON.

Вопрос в том, когда я запрашиваю веб-службу, просто чтобы узнать, действительны ли данное имя пользователя / пароль, должна ли веб-служба всегда отвечать данными JSON, сообщая мне об успешном или неудачном завершении, или должна ли она возвращать HTTP 200 с хорошими учетными данными и HTTP. 401 о неверных учетных данных.

Причина, по которой я спрашиваю, заключается в том, что некоторые другие службы RESTful используют 401 для неверных учетных данных, даже когда вы просто спрашиваете, действительны ли учетные данные. Однако я понимаю, что ответ 401 состоит в том, что они представляют собой ресурс, к которому вы не должны иметь доступ без действительных учетных данных. Но ресурс входа ДОЛЖЕН быть доступен для всех, потому что вся цель ресурса входа в систему - сообщить вам, действительны ли ваши учетные данные.

Другими словами, мне кажется, что запрос вроде:

myservice.com/this/is/a/user/action 

должен вернуть 401, если предоставлены неверные учетные данные. Но просьба вроде:

myservice.com/are/these/credentials/valid

никогда не должен возвращать 401, потому что этот конкретный URL (запрос) авторизован с действительными учетными данными или без них.

Хотелось бы услышать хоть сколько-нибудь обоснованные мнения по этому поводу. Каков стандартный способ решения этой проблемы и является ли стандартный способ решения этой проблемы логически приемлемым?

Мэтт
источник

Ответы:

128

Прежде всего. 401 - это правильный код ответа для отправки в случае неудачного входа в систему.

401 Unauthorized Аналогично 403 Forbidden, но специально для использования, когда требуется аутентификация, но она не удалась или еще не была предоставлена. Ответ должен включать поле заголовка WWW-Authenticate, содержащее запрос, применимый к запрошенному ресурсу.

Ваше замешательство по поводу myservice.com/are/these/credentials/validотправки 401, когда вы просто выполняете проверку, я думаю, основано на том факте, что выполнение логических запросов в REST часто ошибочно из-за ограничений RESTful. Каждый запрос должен возвращать ресурс. Выполнение логических вопросов в службе RESTful - скользкая дорога до RPC.

Теперь я не знаю, как себя ведут сервисы, которые вы просмотрели. Но хороший способ решить эту проблему - иметь что-то вроде объекта Account, который вы пытаетесь получить. Если ваши учетные данные верны, вы получите объект Account, если вы не хотите тратить пропускную способность только для «проверки», вы можете выполнить HEAD на том же ресурсе.

Объект учетной записи также является хорошим местом для хранения всех этих надоедливых логических значений, для которых в противном случае было бы сложно создать отдельные ресурсы.

Клерик
источник
2
Ваша точка зрения о возвращении ресурсов кажется верной, и, возможно, это правильный шаг. Что касается утверждения, что 401 - правильный ответ, я был бы признателен за некоторые пояснения. Я прочитал спецификацию HTTP, которую вы включили сюда, но для меня это не является прямым и очевидным подтверждением вашего утверждения. А именно, проверка подлинности НЕ требуется, чтобы спросить о действительности учетных данных - но то, что вы включили, говорит «специально для использования, когда требуется проверка подлинности».
Мэтт
3
Ваш взгляд на это правильный. Вам не нужно проходить аутентификацию, чтобы иметь возможность запрашивать объект своей учетной записи. Но вам необходимо успешно пройти аутентификацию, чтобы иметь возможность получить ресурс, и это authentication is required and has failed or has not yet been providedприменимо, поскольку вы не запрашиваете действительность учетных данных, а запрашиваете конкретный ресурс на основе предоставленных вами учетных данных.
Cleric
2
Я понимаю, почему вы хотите выполнить «контрольный вызов», и для этого я бы все равно продвигал 401 как соответствующий код ответа для неудачной аутентификации, даже если для вызова не требуется аутентификация. 204 No Content также может подойти, но выглядит немного двусмысленно.
Cleric
4
Я не понимаю, как это может быть правильно, если вы не используете простую или дайджест-аутентификацию. Согласно цитируемой части спецификации: «Ответ должен включать WWW-аутентификацию» - и если вы обратитесь к разделу 14.47: «Процесс аутентификации HTTP-доступа описан в« HTTP-аутентификации: базовая и дайджест-аутентификация доступа ». Это подразумевает для меня, что 401 не подходит, если вы используете
Иона,
1
Я думаю, что это может быть неправильно, я внедряю клиентов как для Интернета, так и для мобильных устройств, и я перехватываю 401 для перенаправления на экран входа в систему. Но когда кто-то уже находится на экране входа в систему и отправляет неправильные учетные данные, в ответе также будет 401 и будет предпринята повторная попытка перенаправления. Должен быть другой код состояния для неудачной попытки аутентификации при явной попытке. Может быть, неправильный запрос или даже ошибка сервера?
Иафет Онгери - инкалимева
27

401 следует отправлять только тогда, когда для запроса требуется поле заголовка авторизации и авторизация не выполняется. Поскольку API входа в систему не требует авторизации, я считаю, что 401 - неправильный код ошибки.

Согласно стандарту здесь https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

* 10.4.2 401 Неавторизованный

Запрос требует аутентификации пользователя. Ответ ДОЛЖЕН включать поле заголовка WWW-Authenticate (раздел 14.47), содержащее запрос, применимый к запрошенному ресурсу. Клиент МОЖЕТ повторить запрос с подходящим полем заголовка авторизации (раздел 14.8). Если запрос уже включал учетные данные авторизации, то ответ 401 указывает, что в авторизации для этих учетных данных было отказано. Если ответ 401 содержит тот же вызов, что и предыдущий ответ, и пользовательский агент уже попытался аутентифицироваться хотя бы один раз, то пользователю СЛЕДУЕТ представить объект, который был указан в ответе, поскольку этот объект может включать в себя релевантную диагностическую информацию. Аутентификация доступа HTTP объясняется в разделе «Аутентификация HTTP: базовая и дайджест-аутентификация доступа» [43]. *

Винксарма
источник
8
Я согласен с вами в этом, но каков альтернативный статус ответа? Я внедряю клиентов как для Интернета, так и для мобильных устройств, и я перехватываю 401 для перенаправления на экран входа в систему. Но когда кто-то уже находится на экране входа в систему и отправляет неправильные учетные данные, в ответе также есть 401 и он снова попытается перенаправить ... что бы вы сделали?
Иафет Онгери - инкалимева
0

Верните 409 с правильным сообщением об ошибке.

креветка
источник