В предыдущей статье мы рассмотрели создание системы аутентификации JWT с использованием библиотек django-rest-framework
и dj-rest-auth
. В этой статье мы рассмотрим, как взаимодействовать с этим сервером из изолированного внешнего интерфейса. Предполагается, что некоторые предварительные знания о:
- Интерфейсный фреймворк, например Vue или React
- Использование клиента, такого как @ vue / cli или Nuxt, для обслуживания внешнего приложения
- Инструменты управления состоянием (например, Vuex или Redux)
- HTTP-клиент Axios
Чтобы просмотреть предыдущую статью, часть 1, нажмите здесь.
В прошлый раз мы создали надежный бэкэнд для JWT с помощью Django. Можно простить мысль, что реализация интерфейса для взаимодействия с ним должна быть тривиальной, особенно с множеством библиотек аутентификации внешнего интерфейса, доступных на npm. Однако у меня не было большого успеха с этими библиотеками, поэтому я предпочитаю просто создавать свои собственные пользовательские формы входа и вызовы API.
На самом деле, при работе с клиентским интерфейсом важно проявлять должную осмотрительность для борьбы с такими атаками, как межсайтовый скриптинг (XSS) и подделка межсайтовых запросов (CSRF). Первое, как правило, представляет большую опасность, чем второе при работе с JWT. В первую очередь следует подумать о файлах cookie.
Файлы cookie и где они хранятся
Если вы следовали последнему руководству, вы должны надеяться, что у вас будет бэкэнд Django, использующий SSL через django-sslserver
, и с локальными обозначениями DNS через /etc/hosts
, которые позволят вам посещать бэкэнд по адресу вроде
https://api.example.com:8000
Для интерфейса я обычно использую Quasar Framework или Nuxt. Как и многие внешние клиенты, которые включают в себя сервер разработки, Quasar использует Webpack под капотом, а сервер разработки webpack имеет параметр https
, который вы можете установить на true
. Это должно позаботиться о внешнем SSL. Не забудьте добавить s
ко всем своим URL-адресам.
Пришло время добавить конечную точку где-нибудь в вашем веб-приложении, которая будет работать с вашей серверной частью. Я оставлю это вам - мы стремимся создать форму входа в систему, которая отправляется на https://api.example.com:8000/login
конечную точку, и, возможно, аутентифицированный маршрут, который должен быть доступен только аутентифицированному пользователю.
В своем браузере (кстати, я лично защищаю браузер Brave, все инструменты разработки Chrome, без шпионажа) откройте свой внешний адрес и введите данные для входа в форму входа. Это отправит POST
запрос в Django, который вернет ваши токены (один токен доступа и один токен обновления).
В этот момент происходит волшебство.
Если вы откроете инструменты разработки Google Chrome или Brave (другие браузеры будут немного другими) и перейдете к Application => Cookies
, вы можете ничего не найти там. Это меня долго смущало. Как оказалось, использование https и настраиваемого DNS, которое мы реализовали в Части 1, теперь приносит свои плоды, и файлы cookie действительно сохраняются - они просто не появляются. Однако, если вы перейдете на Network
и щелкните запрос, сделанный на /login
, теперь рядом с Headers/Preview/Timing
вкладками должна появиться вкладка Cookies
. Если вы затем проверите заголовки доступа, отправляемые с запросами, вы должны увидеть включенные токены доступа.
Использование управления состоянием для контроля аутентификации внешнего интерфейса
Я предпочитаю использовать управление состоянием для написания логики Javascript, но это не обязательно. С этого момента мои фрагменты кода будут относиться к Vuex, но если вы используете что-то еще, например React / Redux, эти концепции все равно должны быть полезны. Я также буду использовать Axios, но вы, вероятно, сможете сделать то же самое с fetch()
.
Важнейшая вещь, которую нужно установить при инициализации Axios, - это установить флаг withCredentials: true
. Вы можете передать этот параметр в любой запрос или установить его по умолчанию следующим образом:
import Vue from 'vue' import axios from 'axios' export default (state) => { axios.defaults.withCredentials = true axios.defaults.baseURL = process.env.API_URL Vue.prototype.$axios = axios state.$axios = axios }
Приведенный выше код может быть найден в загрузочном файле, плагине или где-то еще; это зависит от вашего внешнего интерфейса. Обратите внимание, как я также добавил в состояние Axios, так что теперь я могу использовать его где угодно.
Каждый раз, когда withCredentials = true
, браузер будет включать токены в свои заголовки. Вот пример типичного запроса Axios, помещенного в модуль Vuex:
Мысли на прощание
Независимо от того, пишете ли вы логику внешнего интерфейса с нуля или используете библиотеку, мы надеемся, что это помогло заполнить некоторые пробелы, чтобы ваш интерфейс хорошо работал с серверной частью JWT Django.
Что касается следующих шагов, то еще многое предстоит сделать. Независимо от того, как вы решите реализовать интерфейс, вам, вероятно, следует охватить следующие моменты:
- Добавьте интерфейсные формы, кнопки и HTTP-запросы для каждой нужной серверной конечной точки (например,
/login
,/logout
,/password-change
и т. Д.). - Добавьте конечную точку обновления токена. Также может быть хорошей идеей удалить токен доступа при входе в систему (вы можете сделать это, просто удалив запись
JWT_AUTH_COOKIE
вsettings.py
) и сохранив только токен обновления. Затем вы можете добавить токен доступа в память, нажав конечную точку/refresh-token
, если состояние изменится. - Добавьте перенаправления в логику вашего маршрутизатора, чтобы отправлять пользователя в форму входа, если они не аутентифицированы.
Спасибо, что прочитали эту статью. Если у вас есть какие-либо вопросы или комментарии, напишите мне на johnckealy .dev @ gmail.com.