基于token的鑒權(quán)機(jī)制 — JWT介紹 簡單說是用戶調(diào)登陸接口后服務(wù)端返回一個token费就,前端拿到token放在header里例驹,每次請求的時候傳輸給服務(wù)端,服務(wù)端根據(jù)token驗證,如果有效就繼續(xù),如果無效就立即返回。
- 用jsonwebtoken生成token
- 用express-jwt驗證token是否失效
- 用jsonwebtoken解析出token中的用戶信息蒋搜,比如id
安裝依賴
npm install jsonwebtoken --save
npm install express-jwt
新增server/node_api/src/libs/token.js
文件
import jwt from 'jsonwebtoken'
import config from '../config'
const jwtSecret = process.env.NODE_ENV === 'production' ? config.tokenKey.prod : config.tokenKey.dev
export const generateToken = (userName, userId) => {
return new Promise((resolve, reject) => {
const token = jwt.sign({userName,userId}, jwtSecret, {expiresIn: '24h'});
resolve(token)
})
}
export const getToken = (token) => {
return new Promise((resolve, reject) => {
if(!token) {
reject({error: 'token是空的'})
}else {
console.log('token=',token)
const info = jwt.verify(token.split(' ')[1], jwtSecret)
console.log('info=',info)
resolve(info) //解析返回的值
}
})
}
jwt.sign()傳入需要解析的值,一般為userName判莉,userId豆挽,expiresIn設(shè)置token的過期時間。
打印內(nèi)容如下:
token= bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyTmFtZSI6ImFkbWluIiwidXNlcklkIjoxLCJpYXQiOjE2MDk3NDExNDEsImV4cCI6MTYwOTgyNzU0MX0.JsioftQnZxM5xkfTkAiUjmzW29XGbkx2_H69-xe-iYs
info= { userName: 'admin', userId: 1, iat: 1609741141, exp: 1609827541 }
在app.js中增加一個中間件驗證token是否過期骂租。
app.use((req, res, next) => {
const token = req.headers['authorization']
if(token == undefined) {
next()
}else {
getToken(token).then((data) => {
res.data= data;
next()
}).catch((error) => {
next()
})
}
})
app.use(expressJwt({
secret:'Baohong123456',
algorithms: ['HS256']
}).unless({
path: ['/users/login']
}))
app.use('/', indexRouter)
app.use('/users', usersRouter)
...
// 錯誤處理中間件
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message
res.locals.error = req.app.get('env') === 'development' ? err : {}
// render the error page
res.status(err.status || 500)
if (err.status === 401) {
res.status(401).send('token失效')
}
res.render('error')
})
編輯server/node_api/src/routes/users.js
祷杈,當(dāng)用戶登錄成功后生成token返回給用戶。因為node沒有直接查詢數(shù)據(jù)庫渗饮,而是調(diào)用java提供的登錄接口但汞,如果正常返回就判斷是登陸成功了
router.post('/login', (req, res, next) => {
login({ user_name: 'admin', user_pwd: '666' }).then(result => {
const { result: { data: { data: { user, token } } } } = { result }
generateToken(user.userName,user.id).then(nodeToken => {
res.send({
token,
user,
nodeToken
})
})
})
})
前端在成功調(diào)用登陸接口后拿到返回的token,可以存在localStorage里互站,每次發(fā)送請求的時候吧token放在請求頭即可私蕾。src/libs/axios.js
const token = localStorage.getItem('token')
if(token){
config.headers.authorization = 'Bearer '+token
}