Token Authentication

The basic concept

Understand the limitations of Session authentication

The Session authentication mechanism can be implemented only with cookies. Cookie does not support cross-domain access by default, so when it comes to the front-end cross-domain request back-end interface, a lot of additional configuration is required to achieve cross-domain Session authentication.

Note:

  • You are advised to use the Session authentication mechanism when there is no cross-domain problem between the front-end interface and the back-end interface.
  • The JWT authentication mechanism is recommended instead of Session authentication when the local end needs to request the back-end interface across domains.

What is a token

JWT (JSON Web Token) is currently the most popular cross-domain authentication solution.

The principle of JWT

conclusion:

  1. The user information is stored in the client browser in the form of a Token string.
  2. The server authenticates the user by restoring the Token string.

The composition of JWT

A JWT consists of three parts: Header, Payload, and Signature.

Use the English “between the three.” The format is as follows:

Header.Payload.Signature

/ / column, such aseyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Im5hbWUiOiJ6cyIsInBhc3N3b3JkIjoxMjN9LCJpYXQiOjE2Mzc1MDcyNzksImV4cCI6MTY ZNzUxODA3OX0. 0 o9pcv - 11 sxm8tgmns -- -- S0D - ZnidYZdXLk13V_B35B0Copy the code

The three parts of JWT each stand for

The three components of the JWT are Header, Payload, and Signature.

Among them:

  • Payload is the real user information. It is a string generated after user information is encrypted.
  • The Header and Signature are the security-related parts, which are just to keep the Token secure.

How JWT is used

  • The front end
  1. When the client receives the JWT returned by the server, it usually stores it in localStorage or sessionStorage.
  2. Thereafter, each time the client communicates with the server, it takes this JWT string with it for authentication. The recommended course of action isPut JWT in the HTTP request headerAuthorizationIn the field, the format is as follows:
    Authorization: Bearer [token]
    Copy the code
  • The back-end
    1. If the login succeeds, the token is generated and returned to the browser
    2. Check whether the request header carries the token(except the login page).

Use JWT in Express

Run the following command to install the following two JWt-related packages:

npm i jsonwebtoken express-jwt
Copy the code

Among them:

  • Jsonwebtoken is used to generate JWT strings
  • Express-jwt is used to parse JWT strings back to JSON objects

Define secret key

To ensure the security of JWT strings and prevent them from being cracked by others during network transmission, we need to define a special secret key for encryption and decryption:

① When the JWT string is generated, the secret key needs to be used to encrypt the user information, and finally the encrypted JWT string is obtained

② When parsing JWT strings back to JSON objects, use secret key to decrypt them

const SECRET_KEY = 'login2021'
Copy the code

Generate a JWT string after a successful login

Call the sign() method provided by the JsonWebToken package to encrypt the user’s information into a JWT string and respond to the client:

// v1Router.js
const v1Router = express.Router()
const jwt = require('jsonwebtoken')
const SECRET_KEY = 'login2021'

// Login interface
v1Router.post('/login'.(req, res) = > {
  // Verify password.... (omitted here), if the verification is successful, JWT is generated
  // Parameter 1: information generated into the token
  // Parameter 2: key
  // Parameter 3: Token valid duration: 60, "2 days", "10h", "7d"
  const token = jwt.sign(
    { user: { name: 'zs'.password: 123 } },
    SECRET_KEY,
    { expiresIn: '3h'})console.log('🚀 - > token', token)
  res.send({
    status: 200.message: 'login success! ',
    token,
  })
})	
Copy the code

Parse the JWT string back to a JSON object

Every time the client accesses the authorized interface, it needs to actively send the Token string to the server through the Authorization field in the request header for identity authentication.

At this point, the server can use the express-JWT middleware to automatically parse and restore the Token sent by the client into JSON objects:

// app.js
// Import the token module, parse the JWT string, and restore the JSON object module
const parseJwt = require('express-jwt')
const SECRET_KEY = 'login2021' // Use the same key that generated the token!

// 1. Use middleware to parse tokens
// 2. Use.unless to exclude routes without verification (e.g., login)
app.use(
  parseJwt({
      sectet: SECRET_KEY,
      algorithms: ['HS256'].// Which encryption algorithm is used for parsing
  })
    .unless({ path: ['/v1/login']})// No verification is required for the login page
)
Copy the code

Use req.user to obtain user information

After the express-JWT middleware configuration is successful, the user information parsed from the JWT string can be accessed using the req.user object in those interfaces that have the permission, as shown in the following example:

// This is a privileged API interface
app.get('/admin/getInfo'.(req, res) = > {
    console.log(req.user)
    res.send({
        status: 200.message: 'success'.data: req.user,
    })
})
Copy the code

Error middleware

Unified handling of caught errors

When using Express-JWT to parse the Token string, if the Token string sent by the client is expired or invalid, a parsing failure error will be generated, affecting the normal operation of the project. This error can be caught and handled using Express’s error middleware, as shown in the following code:

// Define error middleware
// middleware/errorhandler.js
function errorHandler(err, req, res, next) {
  console.log(err, err.name);
  let code = 500;
  let message = 'Internal Server Error';
  // Token parsing error
  if (err.name === 'UnauthorizedError') {
    code = 401
    message = 'no login'
  }
  res.statusCode = code;
  res.send({
    status: code,
    message,
  })
}

module.exports = errorHandler
Copy the code
// app.js
const errorhandler = require('middleware')

// Error middleware is written at the end
app.use(errorhandler)
Copy the code

How does the front end use tokens

  1. Save the token
const token = this.axios.post('v1/login', {... });localStorage.setItem('token', token);
Copy the code
  1. Add Authorization carrying token to HEADERS during request
const axios = require('axios').default;
const instance = axios.create({
    baseURL: 'http://localhost:8001/v1'});// Can be added uniformly in axios interception
instance.interceptors.request.use((config) = >{ config.headers = { ... config.headers,// If no 'Bearer 'has been added to the back end, the front end needs to concatenate itself
        Authorization: localStorage.getItem('token'),}})Copy the code

Well, today’s share here ~!