Node uses koa2 to implement a simple JWT authentication method

Node uses koa2 to implement a simple JWT authentication method

Introduction to JWT

What is JWT

The full name is JSON Web Token , which is currently the most popular cross-domain authentication solution. The basic implementation is that after the server authenticates, it generates a JSON object and sends it back to the user. When the user communicates with the server, this JSON object must be sent back.

The JSON looks like this:

{
 "Name": "Zhang San",
 "Role": "Administrator",
 "Expiration time": "July 1, 2018 00:00"
}

Why do we need JWT?

Let's first look at the general authentication process, based on session_id and Cookie implementation

1. The user sends his username and password to the server.

2. After the server verification is passed, relevant data such as user role, login time, etc. are saved in the current session .

3. The server returns a session_id to the user and writes it into the user's Cookie .

4. Each subsequent request by the user will pass session_id back to the server through Cookie .

5. The server receives session_id and finds the previously saved data, thereby knowing the user's identity.

But there is a big problem here. If it is a server cluster, session data sharing is required and each server can read the session. The cost of this implementation is relatively high.

JWT changes the idea and returns JSON data to the front end. When the front end requests again, it sends the data to the back end for verification. That is, the server is stateless, so it is easier to expand.

JWT Data Structure

The three parts of JWT are as follows:

Header , similar to the following

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

alg attribute indicates the signature algorithm ( algorithm ), the default is HMAC SHA256 (written as HS256 ). typ attribute indicates the type of the token . JWT tokens are written as JWT

Payload . It is also a JSON , used to store the actual data that needs to be transmitted. JWT specifies 7 official fields. As shown below

  • iss (issuer): issuer
  • exp (expiration time): expiration time
  • sub (subject): subject
  • aud (audience): audience
  • nbf (Not Before): effective time
  • iat (Issued At): Issue time
  • jti (JWT ID): ID

Of course, you can also customize private fields. But be aware that JWT is unencrypted by default and can be read by anyone, so don't put secret information in this part.

Signature . Signature part is a signature of the first two parts to prevent data tampering. First, you need to specify a secret ). This key is only known to the server and cannot be disclosed to the user. Then, use the signature algorithm specified in Header (the default is HMAC SHA256 ) and generate a signature according to the following formula.

HMACSHA256
 base64UrlEncode(header) + "." +
 base64UrlEncode(payload),
 secret)

After calculating the signature, the three parts of Header , Payload and Signature are combined into a string, each part is separated by a "dot" (.), and then it can be returned to the user. As shown below

Security of JWT

  • JWT is not encrypted by default, but it can be encrypted. Secret data cannot be written into JWT without JWT
  • JWT itself contains authentication information. Once leaked, anyone can obtain all the permissions of the token. To reduce theft, the validity period of JWT should be set to be shorter. For some important permissions, the user should be authenticated again when using them.
  • To reduce theft, JWT should not be transmitted in plain text using HTTP protocol, but should be transmitted using the HTTPS protocol

Node simple demo - implementation of Koa JWT

After talking about theoretical knowledge, let's take a look at how to implement JWT . The general process is as follows:

First, after the user logs in, the server generates and returns token to the client based on the user information. The front end brings token to the server in the next request. After the server verifies that it is valid, it returns the data. If invalid, return 401 status code

Here we use Node to implement it. The two main libraries used are

jsonwebtoken, can generate token , verify, etc.

Koa-jwt middleware further encapsulates jsonwebtoken , mainly used to verify token

Quickly build a koa project

I found that there is currently no official way to quickly build a koa project, like Vue-cli . (It may be that the cost of building a koa project is also low). But I am lazy, so I found a tool - koa-generator, which is relatively easy to use, as follows

Install

npm install -g koa-generator

koa2 my-project creates a new koa2 project called my-project

cd my-project and npm install

Start the project npm start

Open localhost:3000

Generate Token

For the convenience of demonstration, I directly define the variable userList to store user information, which should actually be stored in the database.

const crypto = require("crypto"),
 jwt = require("jsonwebtoken");
// TODO: Use database // This should be stored in a database, but it is just for demonstration let userList = [];

class UserController {
 // User login static async login(ctx) {
  const data = ctx.request.body;
  if (!data.name || !data.password) {
   return ctx.body = {
    code: "000002", 
    message: "Invalid parameter"
   }
  }
  const result = userList.find(item => item.name === data.name && item.password === crypto.createHash('md5').update(data.password).digest('hex'))
  if (result) {
   const token = jwt.sign(
    {
     name: result.name
    },
    "Gopal_token", // secret
    { expiresIn: 60 * 60 } // 60 * 60 seconds
   );
   return ctx.body = {
    code: "0",
    message: "Login successful",
    data: {
     token
    }
   };
  } else {
   return ctx.body = {
    code: "000002",
    message: "Incorrect username or password"
   };
  }
 }
}

module.exports = UserController;

Generate a token through the sign method of jsonwebtoken . The first parameter of this method refers to Payload , which is the data stored in token after encoding. It is also the data that can be obtained after verifying token . The second is the secret key, which is unique to the server. Note that they must be the same during verification in order to be decoded, and it is kept confidential . Generally speaking, it is best to define a public variable. Here it is just for demonstration convenience and is hard-coded directly. The third parameter is option , which can define token expiration time

Client obtains token

After the front-end logs in and obtains token , it can be stored in cookie or in localStorage . Here I save it directly to localStorage

login() {
 this.$axios
  .post("/api/login", {
   ...this.ruleForm,
  })
  .then(res => {
   if (res.code === "0") {
    this.$message.success('Login successful');
    localStorage.setItem("token", res.data.token);
    this.$router.push("/");
   } else {
    this.$message(res.message);
   }
  });
}

Encapsulate axios interceptor and send token to the server for verification in the request header every time a request is made. If it is placed in Cookie before, it can be sent automatically, but this cannot be cross-domain. Therefore, the recommended approach is to put it in the HTTP request header Authorization . Pay attention to the Authorization setting here, and add Bearer in front. For more details, see Bearer Authentication

// axios request interceptor processes request data axios.interceptors.request.use(config => {
 const token = localStorage.getItem('token');
 config.headers.common['Authorization'] = 'Bearer ' + token; // Note the Authorization here
 return config;
})

Verify token

Using koa-jwt middleware for verification is relatively simple, as shown below

// Error handling app.use((ctx, next) => {
 return next().catch((err) => {
   if (err.status === 401) {
     ctx.status = 401;
    ctx.body = 'Protected resource, use Authorization header to get access\n';
   }else{
     throw err;
   }
 })
})

// Note: put it before the route app.use(koajwt({
 secret: 'Gopal_token'
}).unless({ // Configure whitelist path: [/\/api\/register/, /\/api\/login/]
}))

// routes
app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())

It is important to note the following points:

  • secret must be the same as when sign
  • You can configure the interface whitelist through unless , that is, which URL do not need to be verified, such as login/registration.
  • The validation middleware needs to be placed before the route that needs to be validated. The preceding URL cannot be validated.

Demo

If you directly access an interface that requires login, 401 will occur.

Register first, then log in, otherwise it will prompt that the username or password is wrong

After logging in, bring Authorization , you can access normally, return 200 and correct data

Summarize

This article summarizes the knowledge related to JWT authentication and provides a simple demo implemented by koa2 . I hope it will be helpful to everyone.

Due to the length of the article, I have the opportunity to talk about the source code of koa-jwt separately, which is relatively simple~

This article demo address: Client and Server

refer to

JSON Web Token Getting Started Tutorial

Node.js application: Koa2 uses JWT for authentication

This is the end of this article about how to use koa2 in Node to implement a simple JWT authentication method. For more relevant Node koa2 JWT authentication content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Example of how Node.js Koa2 uses JWT for authentication

<<:  Trash-Cli: Command-line Recycle Bin Tool on Linux

>>:  MySQL 5.7.17 installation and configuration method graphic tutorial under Windows 10

Recommend

How to install MySQL 5.7.28 binary mode under CentOS 7.4

Linux system version: CentOS7.4 MySQL version: 5....

A few things you need to know about responsive layout

1. Introduction Responsive Web design allows a we...

JS uses clip-path to implement dynamic area clipping function

background Today, I was browsing CodePen and saw ...

How to deploy Node.js with Docker

Preface Node will be used as the middle layer in ...

Detailed explanation of commonly used CSS styles (layout)

Compatible with new CSS3 properties In CSS3, we c...

Detailed explanation of HTML form elements (Part 1)

HTML forms are used to collect different types of...

VMware installation of Centos8 system tutorial diagram (command line mode)

Table of contents 1. Software and system image 2....

Front-end JavaScript thoroughly understands function currying

Table of contents 1. What is currying 2. Uses of ...

Detailed explanation of common commands in Docker repository

Log in docker login Complete the registration and...

Detailed explanation of JavaScript animation function encapsulation

Table of contents 1. Principle of animation funct...

Example of using supervisor to manage nginx+tomcat containers

need: Use docker to start nginx + tomcat dual pro...

The difference between MySQL database host 127.0.0.1 and localhost

Many of my friends may encounter a problem and do...

Detailed steps for installing MinIO on Docker

Table of contents 1. Check whether the docker env...