Node. JS How to Implement JWT Principle

  • 2021-08-21 19:34:20
  • OfStack

1. Why do you need session management

When we use nodejs to provide resful interface for front-end or other services, http protocol is a stateless protocol. Sometimes we need to obtain whether the specific user has permission according to the request, and operate according to the user's context. Therefore, the emergence of cookies, session and jwt technologies is a supplement to HTTP protocol. So that we can use HTTP protocol + state management to build a user-oriented WEB application.

2. session and cookies

session and cookies are related, session is session_id of the client cookies, and the server stores all the status information of the current user corresponding to session_id. Every time the client requests the server to bring session_id in cookies, the server judges whether there is specific user information, and if not, adjusts the login.

The security of cookies is poor, and an attacker can spoof by acquiring the native cookies or exploit CSRF by exploiting cookies. cookies will have cross-domain problems under multiple domain names The information of session is stored on the server. When node. js deploys multiple machines in stke, it needs to solve the problem of sharing session, which leads to the persistence problem of session. Therefore, session does not support distributed architecture and cannot support scale-out. It can only save session data through database to realize sharing. Authentication failure occurs if the persistence layer fails.

3. Definition of jwt

jwt is the full name of json web token. It solves the problems above session. Its advantage is that the server does not save any session data, that is, the server becomes stateless, which makes it easier to expand. Under what circumstances is it more appropriate to use jwt? I think it is authorized for this scenario. Because jwt is light to use, low in overhead and stateless in the back end, it is widely used.

4. Principle of 4. jwt

The principle of JWT is that after the server authenticates, it generates an JSON object and sends it back to the user, just like the following.


{
 " Name ": " Zhang 3",
 " Role ": " Administrator ",
 " Expiration time ": "2018 Year 7 Month 1 Day 0 Point 0 Points "
}

In the future, when the user communicates with the server, he will send back this JSON object. The server only relies on this object to identify the user. In order to prevent users from tampering with the data, the server will add a signature when generating this object.

5. Authentication process of 5. jwt

Process description:

The browser initiates a request to log in with a user name and password; The server verifies the identity in the database according to the user name and clear code, packages the user identifier to generate token according to the algorithm, The server returns JWT information to the browser, and JWT should not contain sensitive information, which is a very important point The browser initiates the request to obtain the user information, and sends the just obtained token1 to the server, which is generally placed in header, and the field is authorization The server found the information of token, decode and token in the data, and then signed it again to verify the identity; The server returns the user data of the user; The server can set the expiration time in payload, and if it expires, it can ask the client to re-initiate the authentication.

6. Data structure of jwt

jwt contains three parts for using. Style


{ "alg": "HS256", "typ": "JWT"}  
// algorithm => HMAC SHA256
// type => JWT

This is a fixed writing, alg surface to use the HS256 algorithm

Payload Load, Load, JWT specifies 7 official fields


iss (issuer) Issuer 
exp (expiration time) : Expired time 
sub (subject) : Themes 
aud (audience) Audience 
nbf (Not Before) Effective time 
iat (Issued At) : Date of issuance 
jti (JWT ID) Number 

In addition to these 7, you can customize, such as expiration time

Signature Signature

Sign the first two parts header and payload to prevent data tampering


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

secret is a string, which is saved at the back end. It should be noted that JWT is used as a token (token), which may be put into URL in some occasions (such as api. example. com/? token = xxx). Base64 has three characters +,/and =, which have special meanings in URL, so they should be replaced: = is omitted, + is replaced by-,/is replaced by _. This is the Base64URL algorithm.

7. How to use jwt

In the Authorization field of HTTP header information, Bearer is also specified


Authorization: Bearer <token>

Transmit over url (not recommended)


http://www.xxx.com/pwa?token=xxxxx

If it is an post request, it can also be placed in the request body

8. Use in the koa project

You can use an off-the-shelf library, jwt-simple, or jsonwebtoken


let Koa = require('koa');
let Router = require('koa-router');
let bodyparser = require('koa-bodyparser');
let jwt = require('jwt-simple');
let router = new Router()
let app = new Koa();
app.use(bodyparser());
//  You can customize it yourself 
let secret = 'zhenglei';
//  Verify whether to log in 
router.post('/login',async(ctx)=>{ 
  let {username,password} = ctx.request.body;
  if(username === 'admin' && password === 'admin'){
    //  Usually, you look up the database. Here's a simple demonstration 
    let token = jwt.encode(username, secret);
    ctx.body = {
      code:200,
      username,
      token,
    }
  }
});
//  Verify that you have permissions 
router.get('/validate',async(ctx)=>{ 
  let Authorization = ctx.get('authorization')
  let [,token] = Authorization.split(' ');
  if(token){
    try{
      let r = jwt.decode(token,secret);
      ctx.body = {
        code:200,
        username:r,
        token
      }
    }catch(e){
      ctx.body = {
        code:401,
        data:' No landing '
      }
    }
  }else{
    ctx.body = {
      code:401,
      data:' No landing '
    }
  }
 
});
app.use(router.routes());
app.listen(4000);
Implement two interfaces: 1 is/login to verify whether you log in and 1 is validate to verify whether you have permission When requesting the login interface, the client side will bring username and password, and the back end 1 will check the database to verify whether there is a current user. If there is, sign for username, and never bring in the sensitive information of password for signature The client receives the token token from the back end, and then requests other interfaces. For example, when the/validate in this example, when ajax requests, it can specify authorization field in header, and the back end gets token for decode, and then signs header and payload again. If the signatures before and after are 1, it means that they have not been tampered, then the authority verification is passed. Because it is a synchronous process, you can use try catch to catch errors

9. Implementation of principles

sha256 Hash algorithm, you can use nodejs built-in encryption module crypto, base64 string, it should be noted that the generation of base64 needs to be +-= do 1 replacement, = omitted, + replaced with-,/replaced with _. This is the Base64URL algorithm. The token token is composed of header, payload, and sigin through. base64urlUnescape decoding is fixed writing, decode out base64 content

let myJwt = {
  sign(content,secret){
    let r = crypto.createHmac('sha256',secret).update(content).digest('base64');
    return this.base64urlEscape(r)
  },
  base64urlEscape(str){
    return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
  },
  toBase64(content){
    return this.base64urlEscape(Buffer.from(JSON.stringify(content)).toString('base64'))
  },
  encode(username,secret){
    let header = this.toBase64({ typ: 'JWT', alg: 'HS256' });
    let content = this.toBase64(username);
    let sign = this.sign([header,content].join('.'),secret);
    return [header,content,sign].join('.')
  },
  base64urlUnescape(str) {
    str += new Array(5 - str.length % 4).join('=');
    return str.replace(/\-/g, '+').replace(/_/g, '/');
  },
  decode(token,secret){
    let [header,content,sign] = token.split('.');
    let newSign = this.sign([header,content].join('.'),secret);
    if(sign === newSign){
      return Buffer.from(this.base64urlUnescape(content),'base64').toString();
    }else{
      throw new Error(' Be tampered with ')
    }
  }
}

10. Advantages and disadvantages of jwt

JWT is not encrypted by default, but it can be encrypted. After the original token is generated, it can be encrypted again using the modified token. When JWT is not encrypted, some private data cannot be transmitted through JWT. JWT can be used not only for authentication, but also for information exchange. Making good use of JWT helps to reduce the number of requests to the database by the server. The biggest disadvantage of JWT is that the server does not save session state, so it is impossible to cancel the token or change the permissions of the token during use. That is to say, once JWT is issued, it will be valid for 1 straight within the validity period. JWT itself contains authentication information, so anyone can get all the permissions of the token once the information is compromised. In order to reduce embezzlement, the validity period of JWT should not be set too long. For some important operations, users should authenticate every time they use it. To reduce embezzlement and theft, JWT does not recommend using the HTTP protocol for code transmission, but uses the encrypted HTTPS protocol for transmission.

The above is Node. JS how to achieve JWT principle details, more about Node. JS to achieve JWT principle information please pay attention to other related articles on this site!


Related articles: