Учимся работать с аутентификацией в Node используя Passport.js
Перевод статьи Antonio Erdeljac: Learn how to handle authentication with Node using Passport.js
В этой статье вы узнаете, как разработать аутентификацию для вашего Node-сервера используя Passport.js. Эта статья не включает в себя фронт-энд аутентификацию. Используйте её для настройки бэк-энда вашей аутентификации (сгенерировать токен для каждого пользователя и защитить маршруты).
Также помните, что если вы застряли на каком-либо из этапов, вы можете использовать этот GitHub-репозиторий.
В этой статье я научу вас следующему:
- Работать с защищёнными маршрутами
- Работать с JWT (JSON Web Token) токенами
- Обработка неавторизованных запросов
- Создание базовой API
- Создание моделей и схем
Вступление
Что такое Passport.js?
Паспорт — это промежуточное программное обеспечение для Node.js. Ввиду своей невероятной гибкости и модульности, Паспорт может быть закинут в любое веб-приложение на основе Express. Полный набор стратегий поддерживает аутентификацию с помощью имени пользователя и пароля от аккаунтов Facebook, Twitter, и так далее. Больше о Паспорте вы можете прочитать здесь.
Обучение
Создаём с нуля свой node-сервер
Создаём новую директорию с файлом “app.js” внутри:
Теперь установим nodemon для более лёгкой разработки.
А теперь с помощью этого запустим своё приложение “app.js”.
$ nodemon app.js
Создание модели пользователя
Создайте новую папку под названием «models» и создайте файл «Users.js» внутри этой папки. Здесь мы определим нашу «UsersSchema». Мы собираемся использовать JWT
и Crypt
для генерации has
и salt
из полученной строки password
. В дальнейшем это будит использоваться для валидации пользователя.
Теперь добавим только созданную нами модель в “app.js”.
Добавьте следующую строку в ваш файл “app.js” после настройки Mongoose
:
require('./models/Users');
Настройка паспорта
Создайте новую папку с названием “config” и файлом “passport.js” внутри:
В этом файле мы используем метод validatePassword
, который мы описали в User model
. В зависимости от результата, мы возвращаем разный вывод из Паспортной LocalStrategy
.
Теперь подключим “passport.js” к нашему файлу “app.js”. Добавьте следующую строчку ниже всех models
:
require('./config/passport');
Маршруты и опции аутентификации
Создайте новую папку с названием “routes” и файлом “auth.js” внутри.
В этом файле мы использем функцию getTokenFromHeaders
для получения JWT токена, который будет отправлен с клиентской стороны в заголовки запроса. Мы также создаём auth
-объект c optional
и required
свойствами. Мы используем это позже в наших маршрутах.
В той же папке “routes” создайте файл “index.js”:
Теперь нам нужна папка “api” внутри папки “routes” с ещё одним файлом “index.js” внутри.
Теперь давайте создадим файл “users.js”, которым необходим нам в “api/index.js”.
Сперва, мы собираемся создать маршрут необязательной аутентификации ‘/’
, который будет использован для создания новой модели (регистрации).
router.post('/', auth.optional, (req, res, next) ...
После этого мы создаём другой маршрут необязательной аутентификации ‘/login’
. Этот будет использован для активации конфигурации нашего паспорта и подтверждения полученного пароля с помощью электронной почты.
router.post('/login', auth.optional, (req, res, next) ...
Наконец, мы создадим маршрут обязательной аутентификации, который будет использован для возврата текущего зарегистрированного пользователя. Только вошедшие пользователи (пользователи, которые успешно отправили свой токен через заголовки запроса) имеют доступ к этому маршруту.
router.get('/current', auth.required, (req, res, next) ...
Теперь добавим папку наших “routes” в “app.js”. Добавьте следующую строчку ниже require
нашего паспорта:
app.use(require('./routes'));
Тестирование маршрутов
Я буду использовать Postman для отсылки запросов на наш сервер.
Наш сервер принимает следующую форму:
{
"user": {
"email": String,
"password": String
}
}
Создание POST-запроса для создания пользователя
Испытываемая форма:
Ответ:
{
"user": {
"_id": "5b0f38772c46910f16a058c5",
"email": "erdeljac.antonio@gmail.com",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImVyZGVsamFjLmFudG9uaW9AZ21haWwuY29tIiwiaWQiOiI1YjBmMzg3NzJjNDY5MTBmMTZhMDU4YzUiLCJleHAiOjE1MzI5MDgxNTEsImlhdCI6MTUyNzcyNDE1MX0.4TWc1TzY6zToHx_O1Dl2I9Hf9krFTqPkNLHI5U9rn8c"
}
}
Теперь мы используем этот токен и добавим его в наши “Headers” в Postman конфигурации.
А теперь давайте протестируем наш маршрут только аутентификации.
Создаём GET-запрос для возвращения текущего зашедшего пользователя
Запрос URL:
GET http://localhost:8000/api/users/current
Ответ:
{
"user": {
"_id": "5b0f38772c46910f16a058c5",
"email": "erdeljac.antonio@gmail.com",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImVyZGVsamFjLmFudG9uaW9AZ21haWwuY29tIiwiaWQiOiI1YjBmMzg3NzJjNDY5MTBmMTZhMDU4YzUiLCJleHAiOjE1MzI5MDgzMTgsImlhdCI6MTUyNzcyNDMxOH0.5UnA2mpS-_puPwwxZEb4VxRGFHX6qJ_Fn3pytgGaJT0"
}
}
Давайте попробуем сделать это без токена в “Headers”.
Ответ: