Introduction to JWT theory

JSON Web Token Tutorial – Ruanyifeng.com

JWT is what?

  • JWT: JSON Web Tokens
  • Is a cross-domain authentication solution

What problem does JWT solve?

  • Data transmission is simple and efficient
  • JWT generates signatures to ensure transport security
  • JWT is time-sensitive
  • JWT makes more efficient use of clustering for single sign-on

JWT principle

  • After the server authenticates, it generates a JSON object and communicates with the server through JSON

JWT data structure

  • Header
  • Payload
  • Signature (= Signature)

The Header structure

{
    "alg": "HS256"."typ": "JWT"
}
Copy the code

The content structure

The signature

JWT usage mode

  • /api? token=xxx
  • Write token cookie
  • Add token to request header:Authorization:Bearer <token>

Generate tokens through JWT

Jsonwebtoken-npm (npmjs.com)

Back-end project installation

npm install jsonwebtoken
Copy the code

Introduced in /router/users.js

const jwt = require('jsonwebtoken')
Copy the code

Tokens are generated and returned with the interface

// iMOOc is the key
letData = user information object;let token = jwt.sign({
  data,
}, 'imooc', { expiresIn: 30 })
Copy the code

Request to Carry Token

When we log in, the user information is stored in localStorage, including the user’s token information

Therefore, a token is carried in the headers.Authorization request for interception

It should also be added here to determine whether to carry token, because some interfaces do not need token, so we first carry token in each request

/ / request intercept service. Interceptors. Request. Use ((config) = > {const headers = config. The headers. let token = storage.getItem('userInfo') ? storage.getItem('userInfo').token : '' if (! headers.Authorization) { headers.Authorization = 'Bearer ' + token } return config; });Copy the code

Interface Verification Token

const router = require('koa-router') ()const jwt = require('jsonwebtoken');

router.get('/count'.(ctx) = >{
    try {
        // Get the Token carried in the request
        let authorization = ctx.request.header.authorization;
        let token = authorization.split('Bearer ') [1];

        // Verify the Token. If the Token passes the verification, continue. If the Token fails the verification, catch the Token
        let payload = jwt.verify(token, 'imooc');
        
        ctx.body = 'Token verified'
    } catch(e) {
        ctx.body = 'Token verification failed'}})Copy the code

Note about return values and keys:

/** * The key is imooc */
letData = user information object;let token = jwt.sign({
  data,
}, 'imooc', { expiresIn: 30 })

/** * So when the token is verified, the return value is the user information object passed in the previous generation. The key used is also iMOCC */
let payload = jwt.verify(token, 'imooc');
// Payload
> data: {deptId: [].state: 1.role: 1.roleList: [].createTime: "The 2021-10-09 T07:47:36. 566 z",... } > exp:1633765828
> iat: 1633765798
Copy the code

Token to intercept

Here we need to introduce the concept of middleware. There are many middleware uses in app.js;

The following

/** * CTX context object, the same interface as CTX * next() continues to execute */
app.use(async (ctx, next) => {
  await next()
})
Copy the code

Koa – JWT middleware

Koa-jwt-npm (npmjs.com)

The installation

npm i koa-jwt -S
Copy the code

use

const Koa = require('koa')
const app = new Koa()
const koaJwt = require('koa-jwt')
const utils = require('./utils/utils')

app.use(async (ctx, next) => {
  return next().catch((err) = >{
    if(err.status == 401) {
      ctx.status = 200;
      ctx.body = utils.fail('Token authentication failed ', utils.CODE.AUTH_ERROR)
    } else {
      throwerr; }})})// To be placed later, the secret value is the key
app.use(koaJwt({secret: 'imooc'}))
Copy the code

Check whether the Token is verified

Because some interfaces do not require token validation, such as the login interface, we use koA-JWT’s unless method to specify interfaces that do not require token validation.

// For example, no authentication is required for /users/login
app.use(koaJwt({secret: 'imooc'}).unless({ 
    path: [/^/users/login/]
}))

// Users /login = / API /users/login = / API /users/login
// The request received by the backend does not have/API, so be careful not to write/API as well
Copy the code

Query the specified field from the database

Because we’re not going to return all the fields in the database to the client

For example, some sensitive information, such as passwords, will not be returned when a user is queried

So here’s a mongo syntax

// Query conditions
let query = {
  userName,
  userPassword
}

// The field to be queried is a string - multiple fields separated by Spaces
let keys = 'userId userName userEmail'

// user.findone (query condition, field)
let res = await User.findOne(query, keys)
Copy the code

FindOne () returns the specified field, written in three ways

  1. The first is the string form above, where multiple fields are concatenated with Spaces
let keys = 'userId userName userEmail'
let res = await User.findOne(query, keys)
Copy the code
  1. Pass in an object, 1 returns, 0 does not return; (0 and 1, can only write a separate field, can not have a 0, some 1, error)
let keys = {
  userName: 1.userId: 1
}
let res = await User.findOne(query, keys)
Copy the code
  1. throughselect()Method specifies the same value as method one
let keys = 'userId userName userEmail'
let res = await User.findOne(query).select(keys)
Copy the code