Node.js express: login and registration example with jwt – bezkoder

Что такое redis?

Redis это опенсорс (лицензии BSD) хранилище структур данных в оперативной памяти, используемое как база данных, кэш и брокер сообщений — redis.io

Мы собираемся хранить информацию о сессии пользователя в Redis, а не в памяти процесса. Таким образом, наше приложение будет намного проще масштабировать.

Что такое passport.js?

Простая, ненавязчивая аутентификация для Node.js — passportjs.org

Passport — это middleware для проверки подлинности, которую мы собираемся использовать для управления сессиями.

Вступление

В этой статье мы поговорим о том, как работают JSON Web Tokens, каковы
их преимущества, их структура и как их использовать для обработки
базовой аутентификации и авторизации в Express.

Вам не обязательно иметь опыт работы с веб-токенами JSON, поскольку мы
будем говорить об этом с нуля.

Для раздела реализации было бы предпочтительнее, если у вас есть
предыдущий опыт работы с Express , Javascript
ES6 и клиентами REST.

Что такое веб-токены json?

Веб-токены JSON (JWT) были введены как метод безопасного обмена
данными между двумя сторонами. Он был представлен со спецификацией RFC
7519Инженерной группой
Интернета (IETF).

Configure auth key

jsonwebtoken functions such as verify() or sign() use algorithm that needs a secret key (as String) to encode and decode token.

In the app/config folder, create auth.config.js file with following code:

module.exports = {
  secret: "bezkoder-secret-key"
};

You can create your own secret String.

Configure express-session

🛠️️ Next, open index.js and add the following under the Required External Modules section:

const express =require("express");const path =require("path");const expressSession =require("express-session");const passport =require("passport");const Auth0Strategy =require("passport-auth0");require("dotenv").config();

You are adding imports for express-session, passport, and passport-auth0, which you’ll configure in the next sections.

🛠️️ Between the App Variables and App Configuration sections, create two new sections, Session Configuration and Passport Configuration:

const app =express();const port = process.env.PORT||"8000";

Order matters in Express. Please ensure that you add the sections in the right order.

🛠️️ Under Session Configuration, configure expressSession as follows:

const session ={
  secret: process.env.SESSION_SECRET,
  cookie:{},
  resave:false,
  saveUninitialized:false};if(app.get("env")==="production"){
  session.cookie.secure =true;}

expressSession takes a configuration object, session, that defines what options to enable in a session. Here, you are configuring the following options:

Configure passport with the application settings

In this section, you’ll focus on wiring up Passport.js with your Express app.

🛠️️ With Auth0Strategy already imported, proceed to define this strategy under the Passport Configuration section in index.js:

const strategy =newAuth0Strategy({
    domain: process.env.AUTH0_DOMAIN,
    clientID: process.env.AUTH0_CLIENT_ID,
    clientSecret: process.env.AUTH0_CLIENT_SECRET,
    callbackURL: process.env.AUTH0_CALLBACK_URL},function(accessToken, refreshToken, extraParams, profile, done){returndone(null, profile);});

Here, the Auth0Strategy method takes your Auth0 credentials and initializes the strategy. It’s essential to understand what the Auth0Strategy is doing for you:

Create custom middleware with express

🛠️️ In index.js, update the App Configuration section to enhance the response object, res, with data from the authentication server. Do this right above the mounting of the authentication router:

Create node.js express login app

First, we create a folder for our project:

$ mkdir node-js-express-login-example
$ cd node-js-express-login-example

Then we initialize the Node.js App with a package.json file:

npm init
name: (node-js-express-login-example) 
version: (1.0.0) 
description: Node.js Express Login and Registration example
entry point: (index.js) server.js
test command: 
git repository: 
keywords: node.js, express, login, registration, rest api, jwt, authentication, authorization, mysql
author: bezkoder
license: (ISC)
Is this ok? (yes) yes

Further reading

Fullstack CRUD Application:- Vue.js Node.js Express MySQL example- Angular 8 Node.js Express MySQL example- Angular 10 Node.js Express MySQL example- Angular 11 Node.js Express MySQL example- Angular 12 Node.

Deployment:- Deploying/Hosting Node.js app on Heroku with MySQL database- Dockerize Node.js Express and MySQL example – Docker Compose

Log into a node.js express app

🛠️️ Head to the browser tab where your application is running and click the login button to test that it is communicating correctly with Auth0 and that you can get authenticated.

🛠️️ If you’ve set up everything correctly, the application redirects you to the Universal Login page.

Node.js express login example architecture

You can have an overview of our Node.js Express App with the diagram below:

Overview of node.js express login example

We will build a Node.js Express application in that:

These are APIs that we need to provide:

Project structure

This is directory structure for our Node.js Express Login and Registration application:

– config

  • configure MySQL database & Sequelize
  • configure Auth Key

– routes

– middlewares

– controllers

– models for Sequelize Models

– server.js: import and initialize necessary modules and routes, listen for connections.

Set up real-world authentication for node.js

This tutorial’s core objective is to teach you how to set up real-world authentication in a Node.js Express app. For that reason, you’ll start by setting up Auth0 to interact with a real authentication server throughout the tutorial. Otherwise, Passport.js gives you a ton of error messages in the terminal, and the app won’t run.

Auth0 is a global leader in Identity-as-a-Service (IDaaS). Its extensible platform seamlessly authenticates and secures more than 2.5 billion logins per month, making it loved by developers and trusted by global enterprises.

The best part of the Auth0 platform is how streamlined it is to get started by following these three easy steps.

Setup express web server

In the root folder, let’s create a new server.js file:

Source code

You can find the complete source code for this tutorial on Github.

Step 1: sign up and create an auth0 application

🛠️️ If you are new to Auth0, sign up for a free Auth0 account here. A free account offers you:

🛠️️ During the sign-up process, you’ll create something called a Tenant, representing the product or service to which you are adding authentication — more on this in a moment.

🛠️️ Once you are signed in, you are welcomed into the Auth0 Dashboard. In the left sidebar menu, click on “Applications”.

Step 3: add auth0 configuration variables to node.js

🛠️️ Under the project directory, create a hidden file called .env to store configuration variables and secrets that your app needs.

touch .env

Make sure to add this file to .gitignore so that it isn’t committed to version control.

🛠️️ Add the following to .env:

AUTH0_CLIENT_ID=AUTH0_DOMAIN=AUTH0_CLIENT_SECRET=

🛠️️ Head back to your Auth0 application Settings tab and populate each property of the .env hidden file with its corresponding Auth0 application value:

Technology

  • Express 4.17.1
  • bcryptjs 2.4.3
  • cookie-session 1.4.0
  • jsonwebtoken 8.5.1
  • Sequelize 6.11.0
  • MySQL

Use middleware for authentication

As explained in the “Using middleware” section of the Express docs, an Express application is essentially a series of middleware function calls that execute during the request-response cycle. Each function can modify the request and response objects as needed and then either pass control to the next middleware function or end the request-response cycle.

Аутентификация в node.js с использованием passport.js

Перевод книги Node Hero от RisingStack. Переведено с разрешения правообладателей.

Демонстрационное приложение

Для демонстрационных целей создадим приложение, которое умеет только следующее:

Использование jwt с express

В этом руководстве мы создадим простое веб-приложение на основе
микросервисов для управления книгами в библиотеке с двумя сервисами.
Одна служба будет отвечать за аутентификацию пользователей, а другая –
за управление книгами.

Будет два типа пользователей – администраторы и участники .
Администраторы смогут просматривать и добавлять новые книги, а участники

  • только просматривать их. В идеале они также могли бы иметь возможность
    редактировать или удалять книги. Но чтобы статья была как можно проще,
    мы не будем вдаваться в подробности.

Для начала в вашем терминале инициализируйте пустой проект Node.js с
настройками по умолчанию:

 $ npm init -y 

Затем давайте установим фреймворк Express:

 $ npm install --save express 

Книжная служба

После этого давайте создадим books.js для нашего книжного сервиса.

Мы начнем с файла, импортировав необходимые библиотеки и настроив
приложение Express:

 const express = require('express'); 
 const bodyParser = require('body-parser'); 
 const jwt = require('jsonwebtoken'); 
 
 const app = express(); 
 
 app.use(bodyParser.json()); 
 
 app.listen(4000, () => { 
 console.log('Books service started on port 4000'); 
 }); 

После настройки, чтобы смоделировать базу данных, давайте просто
создадим массив книг:

 const books = [ 
 { 
 "author": "Chinua Achebe", 
 "country": "Nigeria", 
 "language": "English", 
 "pages": 209, 
 "title": "Things Fall Apart", 
 "year": 1958 
 }, 
 { 
 "author": "Hans Christian Andersen", 
 "country": "Denmark", 
 "language": "Danish", 
 "pages": 784, 
 "title": "Fairy tales", 
 "year": 1836 
 }, 
 { 
 "author": "Dante Alighieri", 
 "country": "Italy", 
 "language": "Italian", 
 "pages": 928, 
 "title": "The Divine Comedy", 
 "year": 1315 
 }, 
 ]; 

Теперь мы можем создать очень простой обработчик запросов для извлечения
всех книг из базы данных:

 app.get('/books', (req, res) => { 
 res.json(books); 
 }); 

Потому что наши книги должны быть видны только авторизованным
пользователям. Нам нужно создать промежуточное ПО для аутентификации.

Перед этим создайте секрет токена доступа для подписи JWT, как и раньше:

 const accessTokenSecret = 'youraccesstokensecret'; 

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

На этом этапе давайте создадим промежуточное ПО Express, которое
обрабатывает процесс аутентификации:

Обновление токена

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

Если этот токен будет украден, у них будет доступ к учетной записи
навсегда, и фактический пользователь не сможет отозвать доступ.

Чтобы исключить эту возможность, давайте обновим наш обработчик запросов
на вход, чтобы срок действия токена истекал через определенный период.
Мы можем сделать это, передав expiresIn в качестве опции для подписи
JWT.

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

Сначала создайте секрет токена обновления и пустой массив для хранения
токенов обновления:

 const refreshTokenSecret = 'yourrefreshtokensecrethere'; 
 const refreshTokens = []; 

Когда пользователь входит в систему, вместо создания одного токена
генерируйте токены обновления и аутентификации:

Преимущество использования jwt перед традиционными методами

Как мы обсуждали ранее, JWT может содержать всю информацию о самом
пользователе, в отличие от аутентификации на основе сеанса.

Это очень полезно для масштабирования веб-приложений, например
веб-приложений с микросервисами. Сегодня архитектура современного
веб-приложения выглядит примерно так:

<img src="https://rukovodstvo.net/data:image/svg xml,” loading=”lazy” alt=”web_application_architecture”>

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

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

Процесс аутентификации в node.js

Наша цель — реализовать в нашем приложении следующий процесс аутентификации:

  1. Пользователь вводит имя и пароль
  2. Приложение проверяет, являются ли они корректными
  3. Если имя и пароль корректны, приложение отправляет заголовок Set-Cookie, который будет использоваться для аутентификации дальнейших страниц
  4. Когда пользователь посещает страницы в том же домене, ранее установленный cookie будет добавлен ко всем запросам
  5. Аутентификация на закрытых страницах происходит с помощью этого файла cookie

Чтобы настроить такую стратегию аутентификации, выполните следующие три действия:

  1. Настройте Express
  2. Настройте Passport
  3. Добавьте защищённые разделы на сайте

Служба аутентификации

Затем давайте создадим файл auth.js , который будет нашей службой
аутентификации:

 const express = require('express'); 
 const app = express(); 
 
 app.listen(3000, () => { 
 console.log('Authentication service started on port 3000'); 
 }); 

В идеале мы должны использовать базу данных для хранения информации о
пользователях. Но для простоты давайте создадим массив пользователей,
который мы будем использовать для их аутентификации.

Структура jwt

Давайте поговорим о структуре JWT на примере токена:

<img src="https://rukovodstvo.net/data:image/svg xml,” loading=”lazy” alt=”sample_json_web_token_jwt”>

Как вы можете видеть на изображении, JWT состоит из трех частей, каждая
из которых разделена точкой.

Боковая панель: кодирование Base64 – это один из способов убедиться, что
данные не повреждены, поскольку оно не сжимает и не шифрует данные, а
просто кодирует их способом, понятным большинству систем. Вы можете
прочитать любой текст в кодировке
Base64 , просто
декодировав его.

Первый раздел JWT – это заголовок, представляющий собой строку в
кодировке Base64. Если вы расшифруете заголовок, он будет выглядеть
примерно так:

 { 
 "alg": "HS256", 
 "typ": "JWT" 
 } 

Раздел заголовка содержит алгоритм хеширования, который использовался
для генерации знака и типа токена.

Второй раздел – это полезная нагрузка, содержащая объект JSON, который
был отправлен обратно пользователю. Поскольку он закодирован только в
Base64, любой может легко его декодировать.

Рекомендуется не включать в JWT какие-либо конфиденциальные данные,
такие как пароли или личную информацию.

Обычно тело JWT выглядит примерно так, хотя это необязательно:

 { 
 "sub": "1234567890", 
 "name": "John Doe", 
 "iat": 1516239022 
 } 

В большинстве случаев sub свойство будет содержать идентификатор
пользователя, а свойство iat , которое является сокращением для
выданного в , является меткой времени, когда был выпущен токен.

Вы также можете увидеть некоторые общие свойства, такие как eat или
exp , который является сроком действия токена.

Последний раздел – это подпись токена. Это создается путем хеширования
строки
base64UrlEncode(header) “.” base64UrlEncode(payload) secret с
использованием алгоритма, упомянутого в разделе заголовка.

secret – это случайная строка, которую должен знать только сервер.
Никакой хеш не может быть преобразован обратно в исходный текст, и даже
небольшое изменение исходной строки приведет к другому хешу. Таким
образом, secret не может быть реконструирован.

Когда эта подпись отправляется обратно на сервер, она может проверить,
что клиент не изменил никаких деталей в объекте.

Структура проекта

Вы уже научились структурировать Node.js-проекты в предыдущей главе Node Hero, поэтому давайте использовать эти знания!

Мы собираемся использовать следующую структуру:

Технологии, которые мы будем использовать

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

Шаг 2: настройка passport

Passport — отличный пример библиотеки, использующей плагины. В этом уроке мы добавляем модуль passport-local, который добавляет простую локальную стратегию аутентификации с использованием имён пользователей и паролей.

Шаг 3: добавляем защищённые разделы на сайте

Чтобы добавить защищенные разделы на сайт, мы используем шаблон middleware Express. Для этого сначала создадим middleware для аутентификации:

Заключение

В этой статье мы познакомили вас с JWT и как реализовать JWT с Express.
Я надеюсь, что теперь у вас есть хорошие знания о том, как работает JWT
и как реализовать его в своем проекте.

Как всегда, исходный код доступен на
GitHub .

Run & test with results

Run Node.js application with command: node server.js

Tables that we define in models package will be automatically generated in MySQL Database.If you check the database, you can see things like this:

Conclusion

Congratulation!

Today we’ve learned so many interesting things about Node.js Express Login and Registration example with JWT – JSONWebToken by building Rest Apis for Authentication and Authorization.Despite we wrote a lot of code, I hope you will understand the overall architecture of the application, and apply it in your project at ease.

You should continue to know how to implement Refresh Token:JWT Refresh Token implementation in Node.js example

If you need a working front-end for this back-end, you can find Client App in the post:(just modify using Local Storage to Cookies)- Vue- Angular 8 / Angular 10 / Angular 11 / Angular 12 / Angular 13- React / React Hooks / React Redux

Create express authentication endpoints

🛠️️ In this section, you will create three endpoints that handle the application’s authentication flow:

GET /login

GET /logout

GET /callback

To manage these endpoints better, you will create them within an authentication module and export them through an Express router so that your Express application can use them.

🛠️️ To start, create an auth.js file under the project directory.

touch auth.js

Populate it with this template to define its structure:

🛠️️ Next, add the following under the Required External Modules section to import packages that are needed and load your environmental variables:

const express =require("express");const router = express.Router();const passport =require("passport");const querystring =require("querystring");require("dotenv").config();

Here’s an overview of the new modules you are using:

You’ll soon see how these modules streamline your route controller logic.

🛠️️ The first endpoint you’ll create is the GET/login one. Update the Routes Definitions section of your auth.js file as follows:



router.get("/login",
  passport.authenticate("auth0",{
    scope:"openid email profile"}),(req, res)=>{
    res.redirect("/");});

Initialize sequelize

Now create app/models/index.js with content like this:

Похожее:  КАК ПОЛУЧИТЬ ДОСТУП К ПОРТАЛУ ОБСЛУЖИВАНИЯ СОТРУДНИКОВ РЖД

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *