Какой наиболее эффективный способ авторизации в изоморфном spa приложении?
Первым делом хочу обратить внимание что меня интересует сам принцип механизма авторизации, а не принцип привязанный к какому-либо фраймворку.
Архитектура следующая - nginx прокисрует запросы к express.js, который занимается пререндером, для которого данные берутся с api на php.
Я не очень хорошо знаком с вэб, по этому был рад если бы получил краткую инструкцию, как лучше всего реализовать авторизацию, выход и регистрацию при такой архитектуре.
И если для авторизации существуют какие-то инструменты, то расскажите о них.
tasssik: я метеор не сильно пробовал, но мне показалось что эта концепция работает исключительно на небольших или просто простых проектах. Для прототипов в принципе норм.
copal: я храню в local storage (я нахожу защиту от XSS проще чем от CSRF в случае с хранением в куках, тем более что от XSS всеравно надо защищаться). Кто-то в http only куках.
Сергей Протько: спасибо. Только сегодня вплотную подобрался. Решил сначала сделать только с access token, а уже после, а уже как доделаю проект, то попробую с refresh.
Сергей Протько: на клиенте в модели юзера пароль ведь не должен хранится? Я это к тому, что при регистрации я отправляю данные на сервер и после, в том же методе регистрации, я авторизуюсь. Вот так бы взять и вызвать метод авторизации передав в него пароль и логин из аргументов метода register, но ведь используется дата-сторейдж, которая сама делает запросы для получения данных. Но в таком случаи получается что пароль и логин должен быть всегда в модели User. Это нормально?
Сергей Протько: а как быть с токеном из localStorage? Ведь я должен при запуске приложения первым делом авторизовывать юзера, чтобы строить под него интерфейс. А первый запуск происходит ведь на сервере, пререндер, на котором нет LocalStorage и токена...?
Сергей Протько: только вчера настроил сервера и прочие и теперь у меня другой вопрос - а нужен ли вообще jwt? Если единственный выход хранить его в куках, то каково его предназначение, когда есть сессии и куки? И мне кажется что гуглить просто нечего, этим занимаются только на словах. Те кто делал в своем небольшом хелловорд проекте пререндер не делал регистрацию. Тот кто делал регистрацию не делал пререндер. Ну или пререндер не рендерил для авторизованных.
copal: в большинстве случаев для регистрации и авторизации просто формочки, это не SPA даже. То есть как таковой авторизации в SPA нет, есть только аунтефикация. Но это именно те проекты с которыми я сталкивался и скажем так, выборка не репрезентативна. У меня же на проектах пререндер был только для публичных частей приложений не требующих авторизации и только для поисковиков.
Сергей Протько: задавал вопрос в других более узкоспециализированных местах, но к своему сожалению не смог получить ответа. Возможно Вы сможете подсказать, есть ли смысл использовать jwt с куками? Просто мне объясняли что jwt это как идентификатор сессии,
и который в целях оптимизации при аутентификации тоже требует сессий. А ещё мне говорили, что нет смысла использовать jwt + cookie + session, ведь есть уже session_id.
Так вот вопрос - нужен ли в jwt и если да, то какие у него преимущества перед session_id?
copal: JWT позволяет вам хранить частоиспользуемые данные (например юзернейм, роли) прямо в токене и это избавляет клиент от необходимости забирать эти данные с сервера. Если у нас все еще и подпись формируется используя RSA то чисто теоритически можно еще и достоверность данных проверять на клиенте публичным ключем, но я так не делал пока.
По поводу того где нам это дело хранить. Если мы храним JWT токен в HTTP ONLY куках, то толку от JWT нет никакого. Если мы просто храним в куках, то как бы... все ок. Нам даже не надо следить за тем что токен отправляется с каждым запросом - он и так будет. Ну и есть еще безумные варианты удалять это дело из кук, мувать в локал сторадж и оттуда уже по старинке.
По поводу session_id - немного не понял. Если вам не нужна по бизнес логике отдельная сущность сессий - то сессий не будет, будет только токен. Если вам надо дать возможность пользователю закрывать сессии (например как в фэйсбуках или гугл аккаунтах) - то сессии отдельные нужны, связь между сессией и клиентом опять же в токене. То есть сервер всеравно становится stateless.
опять же, смотря от чего вам проще защищаться и каковы риски.
На стороне сервера вначале идёт проверка авторизован пользователь или нет. Если нет, то смотрится с корневого ли роута он пришёл. Если не с корневого то делается редирект на корневой. Для корневого роута неавторизованному пользователю показывается login-page с тупой формой авторизации.
А вот если пользователь уже авторизован, то такой запрос отправляется на React-router, где с контентом страницы на клиентскую сторону в том числе выплёвывается и бандл с клиентским кодом.
Если кратко, то вся изоморфная котовасия (+ соединения по сокету если у вас realtime) начинает работать только для авторизованных клиентов.