В предыдущей статье мы рассмотрели создание системы аутентификации 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.