node.js之express的token验证

1、用jsonwebtoken生成token
2、用express-jwt验证token是否过期或失效
3、用jsonwebtoken解析出token中的用户信息,比如用户id

注意:
使用res.json()发送响应时,需要 return res.json(),类似res.send()等函数也要加return,而且是所有的地方都要加,即使是a请求的响应没加return,当b请求到来时,也会报错:cant’t set headers after they are sent。

报错原因: 默认多次操作res或req

1、新建token_vertify.js文件,用于封装token生成和解析函数

如下:token_vertify.js

var jwt = require('jsonwebtoken');
var signkey = 'mes_qdhd_mobile_xhykjyxgs';

// 签发token
exports.setToken = function(username,userid){
	return new Promise((resolve,reject)=>{
		const token = jwt.sign({
			name:username,
			_id:userid
		},signkey,{ expiresIn:'0.01h' });
		resolve(token);
	})
}

// 验证token
exports.verToken = function(token){
	return new Promise((resolve,reject)=>{
		var info = jwt.verify(token.split(' ')[1],signkey);
		resolve(info);
	})
}

2、在 app.js 中验证token是否过期,如果没过期,则解析出用户信息

app.js中部分代码

var vertoken = require('./token_vertify.js');
var expressJwt = require('express-jwt');

// 解析token获取用户信息,并将用户信息存入 user 中以备使用
app.use(function(req, res, next) {
	var token = req.headers['authorization'];
	if(!token){
		return next();
	} else {
		vertoken.verToken(token).then((data)=> {
			req.user = data;
			return next();
		}).catch((error)=>{
			return next();
		})
	}
});

//验证token是否过期并约定哪些路由不用验证
app.use(expressJwt({
	secret: 'mes_qdhd_mobile_xhykjyxgs'
}).unless({
	path: ['/login']//除了这个地址,其他的URL都需要验证
}));

app.use('/login', loginRouter);
app.use('/users', usersRouter);

//当token失效返回提示信息
app.use(function(err, req, res, next) {
	if (err.status == 401) {
		return res.status(401).send('token失效');
	}
});

// 配置哪些路由需要 jwt 验证哪些不需要,也可以通过在路由中间件第二个参数配置,示例如下:
const expressJwt = require(‘express-jwt’);
const authenticate = expressJwt ({ secret: ‘mes_qdhd_mobile_xhykjyxgs’ });
app.use(‘/auth’, authenticate, loginRouter); // 需要token验证的接口
app.use(‘/notAuth’, usersRouter); // 不需要token验证的接口

3、在路由中使用前面定义的方法

login.js文件

var express = require('express');
var router = express.Router();
var settoken = require('./token_vertify.js');

// 生成token

router.post('/', function(req, res, next) {
	var username = 'slj';
	var userid = "111";
	settoken.setToken(username,userid).then((data)=>{
		return res.json({ token: data });
	})
	return next();
});

module.exports = router;

users.js文件

var express = require('express');
var router = express.Router();

// 身份验证
router.post('/vertify', function(req, res, next) {
	console.log(req.user)
	if(req.user){
		return res.json({
			msg:'身份验证成功'
		})
	}else{
		return res.json({
			msg:'未获取到用户信息'
		})
	}
	next();
});

module.exports = router;

看一下结果:

请求/login生成token并返回给客户端
在这里插入图片描述
成功验证token
在这里插入图片描述
当token失效
在这里插入图片描述
提供打包好的源码下载

  • 12
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
以下是一个使用Node.jsexpress-jwt的完整Token处理和中间件的示例: 1. 安装必要的依赖 ``` npm install express express-jwt jsonwebtoken ``` 2. 创建一个JWT密钥 ``` const jwtSecret = 'mysecretkey'; ``` 3. 创建一个函数来生成令牌 ``` const jwt = require('jsonwebtoken'); function generateToken(user) { const payload = { sub: user.id, iat: Date.now() }; const options = { expiresIn: '1d' }; return jwt.sign(payload, jwtSecret, options); } ``` 4. 创建一个路由来登录并生成令牌 ``` const express = require('express'); const router = express.Router(); const User = require('../models/user'); router.post('/login', (req, res) => { const { email, password } = req.body; User.findOne({ email: email }, (err, user) => { if (err) { return res.status(500).json({ error: err }); } if (!user) { return res.status(401).json({ error: 'User not found' }); } if (!user.validPassword(password)) { return res.status(401).json({ error: 'Invalid password' }); } const token = generateToken(user); res.json({ token }); }); }); module.exports = router; ``` 5. 创建一个中间件来验证令牌 ``` const jwt = require('express-jwt'); function getTokenFromHeader(req) { if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') { return req.headers.authorization.split(' ')[1]; } return null; } const auth = { required: jwt({ secret: jwtSecret, userProperty: 'payload', getToken: getTokenFromHeader }), optional: jwt({ secret: jwtSecret, userProperty: 'payload', getToken: getTokenFromHeader, credentialsRequired: false }) }; module.exports = auth; ``` 6. 使用验证令牌的中间件保护路由 ``` const express = require('express'); const router = express.Router(); const auth = require('../middleware/auth'); router.get('/protected', auth.required, (req, res) => { res.json({ message: 'You are authorized to access this protected route' }); }); router.get('/optional', auth.optional, (req, res) => { res.json({ message: 'This route can be accessed without a token' }); }); module.exports = router; ``` 现在,你可以使用这些路由来生成令牌、保护受保护的路由并允许可选的路由。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值