It is highly recommended to pull the item down before reading the article! Example from my younger brother’s open source project “Project Github”

This article is just a summary of personal learning experience, not authoritative. This is the implementation of the Node server, and the implementation of the front-end will be written later

What is Token authentication

Common Token authentication methods are as follows:

  • OAuth2For example, wechat authorized login (which also seems to be Token authentication)
  • Token authentication based on JWT.KiteBlogThat’s what’s used in there.

Recommended Reading:

JWT ultra detailed analysis

Describe some common login authentication methods. Which one do you use

What is JWT (JSON WEB TOKEN)?

Recommended Reading:

JSON Web Token Introduction tutorial

JSON Web Token – Passes information securely between Web applications

NodeJS (Express) implements Token generation and verification

Install jsonWebToken and Express-JWT

First we install the two middleware, JsonWebToken and Express-JWT

Jsonwebtoken: Used to generate tokens. It also has the ability to parse tokens

Express-jwt: parses the Token (easier than jsonWebToken) and stores the parsed data in requset.user

# Install jsonWebToken NPM I jsonWebTokenCopy the code

To generate the token

If you read the JWT article above, you know that JWT consists of three parts: Payload, Header, and Signature.

Jsonwebtoken gives us the sign(Payload, secretOrPrivateKey, [options, callback]) method. The sign method corresponds to the JWT Signature action

Payload: indicates a load. Parameter type: object secretOrPrivateKey: indicates a user-defined key. The key is sensitive information. Parameter type: string options: Header, load, and algorithm type can be configured. Parameter type: object callback: callback

The payload and options parameters can both be configured. Here is an example. Just choose according to your own habits

The Payload section JWT specifies seven official fields, all of which are optional. The payload parameter can be passed directly as an object.

Iss (issuer) exp (expiration time) sub (Subject) AUD (audience) NBF (Not Before) IAT (Issued) : Issue Time JTI (JWT ID) : NumberCopy the code

Options can also accept the above seven fields, but the field names are different.

iss ---- issuer
exp ---- expiresIn
sub ---- subject
aud ---- audience
nbf ---- notBefore
iat ---- noTimestamp
jti ---- jwtid
Copy the code

In addition, options provides algorithm and header, which correspond to the encryption algorithm used and the HEADER part of JWT respectively. In fact, the algorithm should also belong to the header part.

Having said all this, in fact, we generally use only exp(expiresIn) and algorithm,

Example 1:

The validity period of the token is configured in Options

// Introduce jsonWebToken first
var jsonWebToken = require('jsonwebtoken');

// The key, of course, in real projects the key should be distorted
const SECRET_KEY = 'kite1874'

const token = jsonWebToken.sign({
	// The Payload section provides seven fields, which are omitted here. It can carry some information that can identify the user. Such as userId.
	// Do not use sensitive information, such as passwords, Payload can be parsed.
	userId:user.userId
	role:user.role
},SECRET_KEY,{
	expiresIn:"24h"./ / token is valid
	ExpiresIn: 60 * 60 * 24 * 7
	// algorithm:"HS256" The default algorithm is HS256
})

console.log(token)
Copy the code

Example 2:

We can also set the valid time in payload

const token = jsonWebToken.sign({
	// The value of exp is a timestamp, indicating that the token will expire after 1h
	exp:Math.floor(Date.now() / 1000) + (60 * 60)
	userId:user.userId
	role:user.role
},SECRET_KEY)
Copy the code

Jsonwebtoken in addition to generating tokens, jwT.verify (token, secretOrPublicKey, [Options, callback]) provides a method for parsing and verifying tokens.

I won’t do this here, but if you’re interested, you can refer to the documentation: “JsonWebToken”

Authentication token

Express-jwt is a JWT Token validation middleware developed for the Express framework. Let me start with a brief description of how it is used.

There are two main ways. One is to add validation to requests where they need to be validated. The other is to add validation to all requests and whitelist the requests that do not need validation.

A:

var express = require('express');
var jwt = require('express-jwt');
var app = express();

//SECRET_KEY must be the same as when the Token is generated
const SECRET_KEY = 'kite1874' 

// Secret indicates the key, and algorithms indicates the algorithm. Note that if you generate the Token without setting algorithm manually
// The default is to use HS256 for encryption. "Express-jwt 6.0" requires algorithms: ['HS256'], it's a tear to speak of it!
app.get("/test", 
jwt({ secret: SECRET_KEY, algorithms: ['HS256']}),
function(req,res){
	//do something...
})
Copy the code

After looking at the above example, it is obviously not in line with our overdue, a normal project has dozens of API is a matter of minutes. We can’t just test him one by one

Method 2:

// Registering middleware is equivalent to configuring a global token authentication, unless is the whitelist mentioned above
// Insert the request that does not require token authentication into the path, support array, string, re

app.use(jwt({ secret: SECRET_KEY, algorithms: ['HS256']})
.unless({path: ['/auth/adminLogin'./^\/public\/.*/]}));
// / Auth /adminLogin API and files under public do not require token authentication
Copy the code

This kind of way is convenient a lot of, and more beautiful, maintain rise more convenient also

The user information resolved by Token is stored by defaultreq.user, you can directlyreq.user.userIdTo use the user ID that was entered when the Token was generated

You also use requestProperty and resultProperty to set the object where the user information is stored.

I won’t expand it here, please refer to express-JWT for detailed documentation

Validation error handling

You can use app.use() to register to handle failed validation

App.use (function (err, req, res, next) {if (err. Name === 'UnauthorizedError') {res.status(401). You want to break in? !" )}})Copy the code

Note (personal understanding, not authoritative)

At this point, the generation, verification and verification of the Token are completed without passing error processing. Token generation is generally generated after login, and returned to the front end, the front end to get the Token, and each request API with the Token, Token is equivalent to the identity of the user, do not leak easily.

Once a Token is issued, it cannot be revoked voluntarily. It can only be revoked after its expiration date. This means that even if you change the password, the previous Token is still valid. You can change the key used by the backend to prevent the previous Token from passing, but this means that all the previously generated tokens are invalid and you cannot log out a user. This is obviously not appropriate. Therefore, when a user changes the password, the front-end usually clears the previously saved Token and obtains a new Token

Any friend would think to store tokens on the back end, one for each user. When the account is changed, a new Token is generated to cover the previous Token, but this violates the purpose of using Token, which is to reduce the pressure on the server to a large extent. Store as much information as possible on the client rather than the server.

Use Token can defend against CSRF attack, previously wrote an article about network security, interested friends can see “XSS attack, CSRF attack, SQL injection, traffic hijacking (DNS hijacking, HTTP hijacking) – Browser security”