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:
OAuth2
For example, wechat authorized login (which also seems to be Token authentication)Token authentication based on JWT
.KiteBlog
That’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.userId
To 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”