基于token的鉴权机制 — JWT介绍 简略说是用户调登陆接口后服务端返回一个token,前端拿到token放在header里,每次申请的时候传输给服务端,服务端依据token验证,如果无效就持续,如果有效就立刻返回。
- 用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.devexport 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设置token的过期工夫。
打印内容如下:
token= bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyTmFtZSI6ImFkbWluIiwidXNlcklkIjoxLCJpYXQiOjE2MDk3NDExNDEsImV4cCI6MTYwOTgyNzU0MX0.JsioftQnZxM5xkfTkAiUjmzW29XGbkx2_H69-xe-iYsinfo= { 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
,当用户登录胜利后生成token返回给用户。因为node没有间接查询数据库,而是调用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 }) }) })})
前端在胜利调用登陆接口后拿到返回的token,能够存在localStorage里,每次发送申请的时候吧token放在申请头即可。src/libs/axios.js
const token = localStorage.getItem('token')if(token){ config.headers.authorization = 'Bearer '+token}
参考node.js之express的token验证