OAuth сервер + клиент

scorpion-ds

Новичок
Сейчас закладываю проект, который сам представляет собой REST API (пока не представляет, но хочется верить, что будет представлять) необходимо реализовать авторизацию в этом проекте.

Проект имеет клиент в виде JS (его разработка ушла значительно вперед, но пока полностью отсутствует функционал для взаимодействия с сервером), в дальнейшем возможно будут мобильные приложения, а также друге сервисы которые будет с ним взаимодействовать.

Вчера нагуглил и применил такое решение:
https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/index.md
С ним вроде все просто, но решение показалось "полумерой".

Сегодня решил поэкспериментировать с OAuth, за основу взять вот эту статью:
https://gist.github.com/tjamps/11d617a4b318d65ca583

В целом у меня все получилось, но есть пара вопросов как следует правильней двигаться дальше:

На данный момент, я создаю единственного client, далее используя его client_id и client_secret, а также логин/пароль одного из пользователей, я получаю access_token для дальнейшем работы. client_id и client_secret планирую передавать клиенской части для дальнейшей авторизации (логин/пароль разумеется будет вводиться традиционно).

Таким образом все пользователи будут использовать один и тот же client_id, это нормально?

В целом мне ничего не мешает плодить client_id при каждом подключении клиента, но есть ли в этом смысл?
 

Вурдалак

Продвинутый новичок
В целом мне ничего не мешает плодить client_id при каждом подключении клиента, но есть ли в этом смысл?
OAuth-клиенты — это, грубо, сайты/приложения, поэтому это звучит достаточно странно. К примеру, если бы тут появилась кнопка логина через ВК, то phpclub был бы OAuth-клиентом для OAuth-сервера ВК.

Таким образом все пользователи будут использовать один и тот же client_id, это нормально?
Если пользователи заходят через один и тот же сайт/приложение, то это нормально.

На данный момент, я создаю единственного client, далее используя его client_id и client_secret, а также логин/пароль одного из пользователей, я получаю access_token для дальнейшем работы. client_id и client_secret планирую передавать клиенской части для дальнейшей авторизации (логин/пароль разумеется будет вводиться традиционно).
Получение access_token по secret должно происходить на сервере того сайта, который является OAuth-клиентом (в примере выше — на сервере phpclub.ru), чтобы была гарантия, что запросы идут именно от имени phpclub, т.е. JS-клиент знать secret не должен. Насколько я помню, в OAuth для приложений без северной части (чистые JS-клиенты, iOS/Android) есть специальный flow, который не требует secret'а, а сразу отдаёт access_token.
 

scorpion-ds

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

Получение access_token по secret должно происходить на сервере того сайта, который является OAuth-клиентом (в примере выше — на сервере phpclub.ru), чтобы была гарантия, что запросы идут именно от имени phpclub, т.е. JS-клиент знать secret не должен. Насколько я помню, в OAuth для приложений без северной части (чистые JS-клиенты, iOS/Android) есть специальный flow, который не требует secret'а, а сразу отдаёт access_token.
Понятно, буду разбираться с этим, мне это казалось странным гонять secret, но пока упустил этот момент.
 

Вурдалак

Продвинутый новичок
Получение access_token по secret должно происходить на сервере того сайта, который является OAuth-клиентом (в примере выше — на сервере phpclub.ru), чтобы была гарантия, что запросы идут именно от имени phpclub, т.е. JS-клиент знать secret не должен.
Уточню: я имел в виду, что серверная часть сайта получает access_token по code с использованием secret. Клиент в таком случае не знает ничего кроме code. В этом случае сервер сам выполняет запросы на OAuth-сервер.
В случае implicit grant уже никакого code нет, клиент сразу работает с access_token.

В практическом смысле у чистых JS-клиентов должна быть ссылка с response_type=token: https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/blob/master/Resources/doc/index.md#creating-a-client
 

scorpion-ds

Новичок
Наверно я чего-то не понимаю.

В практическом смысле у чистых JS-клиентов должна быть ссылка с response_type=token: https://github.com/FriendsOfSymfony...ster/Resources/doc/index.md#creating-a-client
Если я не ошибаюсь, то конкретный пример создаст мне ссылку для получения токена с переходом к форме авторизации и подтверждения доступа приложения к API, в моем случае такое решение не подходит, приложение для пользователя должно принимать только логин и пароль, без любых других переходов.

Фактически Клиент и Сервер это одно приложение, но в дальнейшем будут прикручиваться мобильные приложения, потому было решено Клиент разрабатывать максимально независимо.

Сейчас для меня проблема удобно передавать client_id и client_secret в клиент, кастомно закладывать его ни как не хочется.
 

AnrDaemon

Продвинутый новичок
@scorpion-ds, мне кажется, или ты пытаешься использовать неподходящие технолигии?
Попробуй остановиться на секундочку, и нарисовать диаграммку того, что вообще происходит в твоих процессах.
Мне кажется, что у тебя конфликт ожиданий между схемой работы твоего приложения и схемой работы OAuth.
 

Вурдалак

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

Фактически Клиент и Сервер это одно приложение, но в дальнейшем будут прикручиваться мобильные приложения, потому было решено Клиент разрабатывать максимально независимо.
OAuth нужен для предоставления доступа к ресурсам пользователя третьим лицам, т.е. другим сайтам/приложениям, которые не имеют отношения к твоему сайту. Если ты этого не планируешь, то выглядит так, что тебе нафиг не нужен OAuth.

P.S. OAuth предусматривает flow с логином и паролем, но если тебе нужно исключительно это, то опять-таки смысла в OAuth нет.
 

scorpion-ds

Новичок
Это я понимаю, потому первым вариантом было это решение:
https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/index.md
С ним вроде все просто, но решение показалось "полумерой".
Можно в общем-то и самому написать что-то подобное.

OAuth тут конечно избыточен, но зато когда придется подключать "третье" приложение, то в самый раз. В перспективе, обсуждалось (это помимо мобильных приложений), что API должно позволять сторонним приложениям авторизироваться от имени пользователей и выполнять определенные действия, собственно, то что и делает OAuth.

Я с REST со стороны сервера работаю впервые, каким образом лучше организовать авторизацию я пока до конца не понимаю.
 

AnrDaemon

Продвинутый новичок
@scorpion-ds, просто ещё раз напомню, что прежде чем что-то внедрять, надо убедиться, что это что-то действительно подходит для задачи.
JS - клиент, полностью выполняющийся в браузере - где он будет хранить твои токены и секреты?…
 

scorpion-ds

Новичок
@AnrDaemon, пока только эксперименты.
Токены он будет хранить в памяти, после прохождения аутентификации, а вот с секретами проблема.

В общем тогда я в тупике, сейчас вижу первый вариант (у него нет секретов, только токен) или написание ему подобного.
 

AnrDaemon

Продвинутый новичок
Вот именно.
У тебя поток работы, совершенно не подходящий под юз кейс OAuth.
 

Вурдалак

Продвинутый новичок
OAuth тут конечно избыточен, но зато когда придется подключать "третье" приложение, то в самый раз. В перспективе, обсуждалось (это помимо мобильных приложений), что API должно позволять сторонним приложениям авторизироваться от имени пользователей и выполнять определенные действия, собственно, то что и делает OAuth.
Вот когда это понадобится, тогда и займетесь решением этой проблемы. Можно либо запилить OAuth API отдельно (это нормальная практика, он обычно намного беднее), либо добавить аутентификацию в существующий API с access_token.
 

scorpion-ds

Новичок
Хорошо, думаю OAuth можно пока отложить.

Тогда вопрос, уже не связанный с ним или скорее интересует опыт других, как все же лучше подойти к аутентификации и авторизации?

Мое первое решение было писать все самому, но по сути использовать шпаргалку:
http://symfony.com/doc/current/cookbook/security/api_key_authentication.html
Не приступал, так как нашел второе решение ...

Второе, которое было для теста реализовано:
https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/index.md
готовое решение и довольно простое в использовании, имеется только токен, который можно получить указав логин/пароль пользователя.

Или я может чего-то не понимаю?
 

AnrDaemon

Продвинутый новичок
Думаю, ты понимаешь, просто пока не осознаёшь.
Авторизация и аутентификация - это два разных процесса. Их взаимосвязь - вещь неочевидная и часто несущественная в контексте каждого отдельно взятого запроса.
 

Redjik

Джедай-мастер
single sign on хватит вполне для такого
OAuth тут конечно избыточен, но зато когда придется подключать "третье" приложение, то в самый раз. В перспективе, обсуждалось (это помимо мобильных приложений), что API должно позволять сторонним приложениям авторизироваться от имени пользователей и выполнять определенные действия
 
Сверху