Как получить информацию о пользователе после аутентификации REST на стороне клиента?

У меня есть бэкэнд Spring REST и интерфейс Angular.

Аутентификация выполняется с помощью POST-запроса к URL-адресу «/login» с именем пользователя и паролем внутри тела запроса JSON (я использую аутентификацию на основе формы). Серверная часть REST отвечает кодом OK. Все в порядке, и я могу выполнять другие запросы из внешнего интерфейса, требующие аутентификации.

Но веб-интерфейс должен знать, какова роль аутентифицированного пользователя, чтобы он мог отображать для него правильное представление/запись. А где взять эту роль на фронтенде? Единственный ответ, который мы получили от проверки подлинности, был в порядке, и это нормально для REST.

Мы можем получить информацию о пользователе, выполнив запрос GET к «/users/[user_id]». Но у нас нет идентификатора пользователя, только имя пользователя.

Итак, вопрос: какой правильный способ для REST получить роль (или другую информацию о пользователе) из внешнего интерфейса, имеющего только имя пользователя?

В качестве обходного пути я могу создать новый запрос на серверной части, который принимает имя пользователя вместо идентификатора, или я могу добавить идентификатор пользователя в ответ аутентификации. Но я не совсем уверен, что это правильный путь с точки зрения REST.


person nickolay.laptev    schedule 29.10.2016    source источник
comment
Если ваш бэкенд требует передачи идентификатора пользователя для получения текущей информации о пользователе, но не позволяет получить идентификатор пользователя, то у бэкенда есть серьезная проблема с дизайном. Кажется, вы можете отправить запрос, требующий аутентификации. Это означает, что серверная часть может идентифицировать вас (вероятно, благодаря куки). Если это так, вам не нужно ничего передавать в качестве параметра, так как он неявно передается в файле cookie. Вы можете просто иметь ресурс /current-user.   -  person JB Nizet    schedule 29.10.2016
comment
И backend, и frontend разрабатываются мной. Как серверная часть правильно предоставляет информацию о пользователе после REST?   -  person nickolay.laptev    schedule 29.10.2016
comment
Я только что тебе сказал. Предполагая, что серверная часть имеет неявный способ идентификации запросов (например, с помощью файла cookie), вы можете просто предоставить ресурс /current-user или /me или как вы хотите его назвать. См. developer.github.com/v3/users/#get-the -аутентифицированный-пользователь например.   -  person JB Nizet    schedule 29.10.2016
comment
Будет ли это хорошо с точки зрения REST? Я не уверен, что означает POST/current-user или DELETE/current-user.   -  person nickolay.laptev    schedule 29.10.2016
comment
Как вы думаете, почему каждый ресурс должен поддерживать действие удаления или публикации?   -  person JB Nizet    schedule 29.10.2016
comment
Я действительно плохо разбираюсь в REST, но я понимаю, что вы должны думать об операциях DELETE, POST и т. д., когда добавляете ресурс в службу REST. Спасибо за ссылку. Кажется, правильный дизайн серверной службы заключается в том, чтобы иметь конечную точку users/:username вместо users/:userid?   -  person nickolay.laptev    schedule 29.10.2016
comment
Если имя пользователя является уникальным идентификатором пользователя, то да. Ваше понимание неверно. Если ресурс доступен только для чтения, то нет смысла предоставлять для этого ресурса методы DELETE и POST. Вы заметили, что API github использует только /user для получения аутентифицированного пользователя?   -  person JB Nizet    schedule 29.10.2016
comment
Отлично. Спасибо.   -  person nickolay.laptev    schedule 29.10.2016
comment
@JBNizet, не могли бы вы перенести свои предложения относительно дизайна конечных точек (например, иметь /users/:name вместо /users/:id) в отдельный ответ, чтобы я мог пометить его как ответ? В противном случае я сделаю это сам, но это может усложнить понимание для других.   -  person nickolay.laptev    schedule 30.10.2016


Ответы (4)


Вы не можете переопределить HTTP-методы. Поэтому, если вы планируете написать вызов GET с разными параметрами запроса с одним и тем же путем, это не разрешено. Вам нужно написать два пути GET.

e.g.

GET /users/userid/{id} GET /users/username/{name}

И во втором вызове вы можете добавить желаемую логику для получения роли во втором.

person Sakalya    schedule 29.10.2016
comment
Но с точки зрения REST я не уверен, что это правильно. Что означает DELETE /users/username? - person nickolay.laptev; 29.10.2016
comment
Если вы не хотите разрешать DELETE, не пишите реализацию для вызова DELETE. Это вполне приемлемо в соответствии со стандартом REST. - person Sakalya; 29.10.2016

Есть два способа сделать это.

1) После успешной аутентификации с сервера выполните еще один вызов $http на сервер с именем пользователя, из которого вы можете получить информацию из логики сервера, которая извлекает и сохраняет этот результат в $rootScope. Эта информация будет доступна через приложение.

2) Когда вы аутентифицируете пользователя, если пользователь действителен, извлеките его данные и сохраните их в объекте.

Теперь в логике вашего сервера при возврате ответа вы можете сделать, как показано ниже.

response.setHeaders("User",userDetilsObj);

ПРИМЕЧАНИЕ: ответ представляет собой объект HttpServletResponse.

После того, как запрос будет выполнен, как вы сказали, мы получим ответ OK со статусом 200. Чтобы получить доступ к данным пользователя на стороне JS, следуйте приведенному ниже коду.

if(response.status == '200/OK'){
   $rootScope.user = response.getHeaders().User;//In this object all the user details set at server side are available now..
}

Надеюсь, это прольет свет на то, как достичь желаемых результатов.

person ngCoder    schedule 30.10.2016
comment
Спасибо. Эти два способа очень похожи на обходные пути, о которых я упоминал в вопросе. А вопрос о другом. JB Nizet указал, что замена /users/:id на конечную точку /users/:name допустима с точки зрения дизайна, так что это отвечает на мой вопрос. - person nickolay.laptev; 30.10.2016
comment
да, согласен, но вы спросили, какой способ сделать это лучше, поэтому я бы предложил использовать первый подход, который чище и удобнее в сопровождении. - person ngCoder; 30.10.2016
comment
Использование /users/:name не является более чистым подходом, потому что идентификатор - это то, что останется навсегда постоянным, имя может быть изменено или может быть чувствительным к регистру, что снова требуется преобразование, что, если у вас есть больше пользователей с тем же именем? Как вы определите, кто из них вошел в систему? - person ngCoder; 30.10.2016
comment
Просто прочитайте мой вопрос и нашу дискуссию с @JBNizet, и это убережет ваше время от повторения этого вопроса и слов JBNizet. - person nickolay.laptev; 30.10.2016

Получите информацию о пользователе с сервера во время аутентификации пользователя. Передайте данные пользователя при успешной аутентификации пользователя.

person Ajit    schedule 31.10.2016

После обсуждения проблемы с @JBNizet в комментариях я решил изменить конечную точку REST с «/users/:user_id» на «/users/:user_name».

person nickolay.laptev    schedule 31.10.2016