JWT profile

What is the JWT

JSON Web Token is the most popular cross-domain authentication solution. The basic implementation is that the server generates a JSON object after authentication and sends it back to the user. Whenever the user communicates with the server, it sends back this JSON object.

The JSON is similar to the following:

{
  "Name": "Zhang"."Role": "Administrator"."Due Time": "0:0 on July 1, 2018."
}
Copy the code

Why do YOU need JWT

Let’s take a look at the general authentication process, based on session_ID and Cookie implementation

  • The user sends the user name and password to the server.
  • After the server validates, the current dialog (session) to save relevant data, such as user role, login time and so on.
  • The server returns one to the usersession_id, written to the userCookie.
  • Each subsequent request from the user will passCookieThat will besession_idReturn to the server.
  • Server receivedsession_id, find the data saved in the early stage, thus know the identity of the user.

However, there is a big problem, if the server cluster, requires session data sharing, each server can read the session. This implementation cost is relatively large.

JWT converts the idea by returning JSON data to the front end, which sends the data to the back end for verification when the front end requests again. The server is stateless, so it’s easier to scale.

JWT data structure

The three parts of JWT are as follows:

  • Header(head), similar to below
{
  "alg": "HS256"."typ": "JWT"
}
Copy the code

The alG attribute represents the algorithm of the signature. The default value is HMAC SHA256 (written as HS256). The TYp attribute represents the type of the token, and the JWT token is written as JWT

  • Payload. It’s also a JSON file that holds the actual data that needs to be passed. The JWT specifies seven official fields. As shown below.

  • Iss (Issuer) : indicates the issuer

  • Exp (expiration Time) : expiration time

  • Sub (subject) : indicates the topic

  • Aud (audience) : Audience

  • NBF (Not Before) : indicates the effective time

  • Iat (Issued At) : time of issue

  • Jti (JWT ID) : indicates the ID

You can also customize private fields. Note, however, that JWT is unencrypted by default and anyone can read it, so don’t put secret information in this section.

  • Signature(Signature).SignatureThe part is the signature of the first two parts to prevent data tampering. First, you need to specify a key (secret). This key is known only to the server and cannot be disclosed to users. Then, useHeaderThe signature algorithm specified inside (default isHMAC SHA256), generate the signature according to the following formula.
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
Copy the code

After calculating the Signature, add the Header, Payload, and Signature parts into a string, and use dots (.) between each part. Delimit, and it can be returned to the user. As shown below.

The safety of the JWT

  • JWT is not encrypted by default, but it can be encrypted. Secret data cannot be written to the JWT without encryption

  • The JWT itself contains authentication information, and if it is disclosed, anyone can gain full access to the token. To reduce theft, JWT expiration dates should be shorter. For some important permissions, the user should be authenticated again

  • To reduce theft, JWT should use HTTPS instead of HTTP

Node simple demo – implementation of Koa JWT

After finishing the 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 the token to the client based on the user information. The front-end brings the token to the server in the next request. After the server verifies the validity, the server returns the data. If not, return the 401 status code

Here we use Node implementation, the main use of two libraries are

  • jsonwebtoken, can generatetoken, check etc.
  • Koa – JWT middleware 对 jsonwebtokenFurther encapsulation, mainly for verificationtoken

Build a KOA project quickly

It was discovered that there is currently no official way to quickly build koA projects, like vue-CLI. (It may also be cheap to set up a KOA project). Lazy me, however, found a tool, koA-Generator, which is relatively simple to use

  • The installation
npm install -g koa-generator
Copy the code
  • koa2 my-projectCreate a new one calledmy-projectkoa2project
  • cd my-projectnpm install
  • Start the projectnpm start
  • Open thelocalhost:3000

To generate the Token

For the sake of demonstration, I have directly defined the variable userList to store the user’s information, which should be stored in the database.

const crypto = require("crypto"),
  jwt = require("jsonwebtoken");
// TODO:Using a database
// This is just a demo
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 s
      );
      return ctx.body = {
        code: "0".message: "Login successful".data: {
          token
        }
      };
    } else {
      return ctx.body = {
        code: "000002".message: "Wrong username or password"}; }}}module.exports = UserController;
Copy the code

Generate a token through the sign method of jsonWebToken. The first parameter of this method refers to the Payload, which is the encoded data stored in the token and the data that can be retrieved after the token verification. The second is the secret key, server side unique, pay attention to the verification of the time to the same to decode, and is confidential, generally speaking, it is best to set the public variables, here is just a demonstration of convenience, directly write dead. The third parameter is option, which defines the token expiration time

The client obtained the token

After the front-end login obtains the token, it can be stored in the cookie or localStorage. So I’m going to store it directly in 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); }}); }Copy the code

Encapsulates the axios interceptor and sends the token to the server for validation with each request. If you put it in a Cookie before, you can make it send automatically, but it doesn’t cross domains. Therefore, the recommended practice is to place it in the HTTP request header Authorization. Note the Authorization Settings here, with Bearer in front. Details can be found in Bearer Authentication

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

Check token

Koa-jwt middleware is used for verification in a relatively simple way, 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{
          throwerr; }})})// Note: Put it in front of the route
app.use(koajwt({
  secret: 'Gopal_token'
}).unless({ // Configure the whitelist
  path: [/\/api\/register/./\/api\/login/]}))// routes
app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())
Copy the code

The following points need to be noted:

  • secretMust andsignBe consistent
  • Can be achieved byunlessConfigure the interface whitelist, that is, which onesURLCan not be verified, such as login/registration can not be verified
  • The verification middleware must be placed in front of the route to be verifiedURLcheck

demo

  • If you directly access the interface that you need to log in to401

  • Register first and then log in. Otherwise, the user name or password will be incorrect

  • Log in withAuthorization, which can be accessed normally200And the right data

conclusion

This article summarizes the knowledge related to JWT authentication and provides a simple demo of the KOA2 implementation that you hope will be helpful.

Subject to space, there is an opportunity to say the koA-JWT source alone, but also relatively simple ~

The demo addresses of this article are Client and Server

reference

  • JSON Web Token Tutorial
  • Node.js application: Koa2 uses JWT for authentication