Passport is commonly used for Token authentication on Node.js. It can customize the verification policy, but if you are using the Express framework and are parsing simple requirements like JWT, express-JWT can be used instead.
About the JWT
JWT is a solution to replace the traditional session authentication. The idea is that the server generates a JSON object containing the user’s unique identity and issues it to the client. When a client requests an interface that requires permissions, it simply sends the JSON back to the server as it is, and the server can parse it to identify the user.
It usually looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJ SMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cCopy the code
The JSON object is divided into three segments via. And contains the request header (encryption algorithm), payload information (such as userId, expiration time), and the signature generated by the server key to ensure it is not tampered with.
This mechanism eliminates the need for servers to store tokens and is therefore a very lightweight user authentication scheme. In addition, JWT is currently the first choice for cross-domain authentication of micro-services, which requires Token sharing between different services.
About the express – JWT
Express-jwt is an open source library for Node.js, developed by ID authentication service provider Auth0. Express-jwt is a middleware specifically designed to parse JWT under the Express framework.
It is very simple to use, and automatically assigns the payload part of the JWT to req.user, so that the logical part can be called easily.
Begin to use
The installation
npm install express-jwt
Copy the code
Join middleware
const expressJwt = require('express-jwt')
app.use(expressJwt({
secret: 'secret12345' // Signature key or PublicKey
}).unless({
path: ['/login'.'/signup'] // The specified path does not pass Token resolution
}))
Copy the code
To generate the Token
The Token generation method still uses jsonWebToken, such as adding the following code to the return part of the login interface:
const jwt = require('jsonwebtoken')
app.post('/login'.function (req, res) {
// Note that the default Token must start with Bearer+ space
const token = 'Bearer ' + jwt.sign(
{
_id: user._id,
admin: user.role === 'admin'
},
'secret12345',
{
expiresIn: 3600 * 24 * 3
}
)
res.json({
status: 'ok'.data: { token: token }
})
})
Copy the code
Get parsed content
When a Token request is received and resolved successfully, it can be accessed via req.user in the route callback:
app.get('/protected'.function (req, res) {
if(! req.user.admin)return res.sendStatus(401)
res.sendStatus(200)})Copy the code
Req. user is actually the payload portion of the JWT:
{
_id: '5dbbc7daaf7dfe003680ba39'.admin: true.iat: 1572587484.exp: 1573192284
}
Copy the code
Parse failure
If parsing fails, an UnauthorizedError is raised, which can be captured by the backend middleware:
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401).send('invalid token')}})Copy the code
Modify result field
The default parse result is assigned to req.user, which can also be changed by requestProperty:
app.use(expressJwt({
secret: 'secret12345'.requestProperty: 'auth'
}))
Copy the code
Tokenless requests are allowed
When the interface allows access to both tokenless and tokenless states (such as post details login for a thumbs up), tokenless requests can be resolved and exceptions can be thrown by credentialsRequired: False.
app.use(expressJwt({
secret: 'secret12345'.credentialsRequired: false
}))
Copy the code
Custom parsing
By default, Express-JWT retrieves the Token from the Authorization field of the Headers request and resolves it.
GetToken also allows you to customize some of the parsing logic, such as using other Header fields and custom exceptions:
app.use(expressJwt({
secret: 'secret12345'.credentialsRequired: false.getToken: function fromHeaderOrQuerystring (req) {
if (req.headers.authorization && req.headers.authorization.split(' ') [0= = ='Bearer') {
return req.headers.authorization.split(' ') [1]}else if (req.query && req.query.token) {
return req.query.token
}
return null}}))Copy the code
Revocation of Token
In JWT, since tokens are not usually stored, revoking a Token is usually done in a passive manner.
A common way to do this is to create a blacklist of fields (such as TokenId) and filter all tokens. Express-jwt specifically provides callbacks to handle this situation:
const expressJwt = require('express-jwt')
const blacklist = require('./blacklist')
let isRevokedCallback = function(req, payload, done){
let issuer = payload.iss
let tokenId = payload.jti
blacklist.getRevokedToken(issuer, tokenId, function(err, token){
if (err) { return done(err) }
return done(null,!!!!! token)// If the second argument is true, it will not pass
})
}
app.use(expressJwt({
secret: 'secret12345'.isRevoked: isRevokedCallback
}))
Copy the code
See the official documentation for more usage
This article belongs to the original content, first published in the wechat public account “life oriented programming”, if you need to reprint, please leave a message in the public account background.