Я знаю, что это не первый раз, когда тема рассматривается в StackOverflow, однако у меня есть некоторые вопросы, на которые я не мог найти ответ или другие вопросы, которые противоречили ответам.
Я делаю довольно простой REST API (Silex-PHP), который должен быть изначально использован только одним SPA (базовым приложением). Я не хочу комментировать все несколько методов проверки подлинности в этом вопросе, поскольку эта тема уже полностью включена в SO. Я в основном создаю токен для каждого пользователя, и этот токен будет прикреплен в каждом запросе, который требует аутентификации со стороны SPA. Все транзакции SPA-Server будут работать под HTTPS. На данный момент мое решение заключается в том, что токен не истекает. Токены, которые истекают/токены за сеанс, не соответствуют безгражданству REST, не так ли? Я понимаю, что там есть много возможностей для улучшения безопасности, но пока что я пока недоступен.
У меня есть модель для токенов и, следовательно, таблица в базе данных для токенов с FK для user_id. Под этим я подразумеваю, что токен не является частью моей модели пользователя.
REGISTER
У меня есть POST/users (не требует аутентификации), который создает пользователя в базе данных и возвращает нового пользователя. Это соответствует одному правилу одного запроса. Однако это вызывает у меня определенные сомнения:
-
Моя идея заключается в том, что на момент создания нового пользователя создайте новый токен для пользователя, чтобы немедленно вернуть его с помощью Response и, таким образом, улучшить UX. Пользователь сразу же сможет начать использовать веб-приложение. Однако возврат маркера для такого ответа приведет к нарушению правила возврата только ресурса. Должен ли я вместо этого сделать два запроса вместе? Один, чтобы создать пользователя и один для извлечения токена без необходимости повторного ввода учетных данных пользователям?
-
Если я решил вернуть токен вместе с пользователем, то я считаю, что POST/пользователи будут путать для потребителя API, а затем появится что-то вроде POST/auth/register. Еще раз мне не нравится эта идея, потому что она включает в себя глагол. Мне очень нравится простота, предлагаемая в этом ответе. Но опять же, мне нужно будет сделать два запроса вместе, POST/users и POST/tokens. Как неправильно делать два запроса вместе, а также, как я точно отправлю соответствующую информацию для токена, который будет прикреплен к определенному пользователю, если оба запроса отправлены вместе?
Теперь мой поток работает следующим образом:
1. Register form makes a POST /users request
2. Server creates a new user and a new token, returns both in the response (break REST rule)
3. Client now attaches token to every Request that needs Authorization
Знак не истекает, сохраняя безгражданство REST.
ЭЛЕМЕНТНОЕ ПОЛОЖЕНИЕ
Большинство текущих веб-приложений требуют проверки подлинности электронной почты, не нарушая UX для пользователей, то есть пользователи могут сразу использовать webapp после регистрации. С другой стороны, если я верну маркер с запросом на регистрацию, как было предложено выше, пользователи сразу получат доступ к каждому ресурсу без проверки электронной почты.
Обычно я бы использовал следующий рабочий процесс:
1. Register form sends POST /users request.
2. Server creates a new user with validated_email set to false and stores an email_validation_token. Additionally, the server sends an email generating an URL that contains the email_validation_token.
3. The user clicks on the URL that makes a request: For example POST /users/email_validation/{email_validation_token}
4. Server validates email, sets validated_email to true, generates a token and returns it in the response, redirecting the user to his home page at the same time.
Это выглядит сложнее и полностью разрушает UX. Как ты это сделал?
ВХОД
Это довольно просто, потому что теперь я делаю это так, поэтому, пожалуйста, исправьте меня, если не так:
1. User fills a log in form which makes a request to POST /login sending Basic Auth credentials.
2. Server checks Basic Auth credentials and returns token for the given user.
3. Web app attached the given token to every future request.
логин - это глагол и, таким образом, нарушает правило REST, все, похоже, соглашаются на это так.
LOGOUT
Почему всем кажется, что нужна конечная точка /auth/logout? С моей точки зрения, нажатие на "выход из системы" в веб-приложении должно в основном удалить токен из приложения и не отправлять его в дополнительные запросы. Сервер не играет никакой роли.
Как возможно, токен хранится в localStorage, чтобы предотвратить потерю маркера при возможном обновлении страницы, выход из системы также подразумевал бы удаление токена из localStorage. Но все равно это не влияет на сервер. Я понимаю, что люди, которые должны иметь POST/logout, в основном работают с токенами сеанса, которые снова нарушают безгражданство REST.
ПОМНИТЕ ME
Я понимаю, что помню, что я в основном ссылаюсь на сохранение возвращенного токена на localStorage или нет в моем случае. Правильно ли это?
Если вы порекомендовали бы какие-либо дальнейшие чтения по этой теме, я очень благодарен. Спасибо!