NodeJs使用jwt生成token以及使用express-jwt校验和解密token
/注:校验token,获取headers⾥里里的Authorization的token方法,要写在路由加载之前,静态资源之后
app.use(expressJWT({
secret: PRIVATE_KEY
}).unless({
path: ['/api/user/register','/api/user/login'] //⽩白名单,除了了这⾥里里写的地址,其他的URL都需要验证
}));
一、生成token
1、安装jsonwebtoken
npm install jsonwebtoken -S
2、在公共文件中定义一个秘钥和过期时间(单位是秒)
module.exports = {
"PRIVITE_KEY":"我是秘钥",
"EXPIRESD":60*60*24
}
3、在需要生成token的页面引入jsonwebtoken(路由页面)
// jwt生成token
var {PRIVITE_KEY,EXPIRESD} = require("../utils/store")
const jwt = require("jsonwebtoken");
//jwt.sign()方法可生成token,第一个参数写的用户信息进去(可以写其他的),第二个是秘钥,第三个是过期时间
let token = jwt.sign({username},PRIVITE_KEY,{expiresIn:EXPIRESD});
二、校验和解密token(此方法写在静态资源加载之后,不然静态资源不能访问))
1、安装express-jw
npm install express-jwt
2、校验token,获取headers⾥里里的Authorization的token
前端token值格式 Bearer+token 这是express-jwt规定的前端格式
在入口文件app.js中引入express-jw以及token加密时使用的秘钥
const expressJWT = require('express-jwt');
var { PRIVITE_KEY } = require("./utils/store");
//使用此方法拦截所有请求看token是否正确(此方法写在静态资源加载之后,不然静态资源不能访问)
app.use(expressJWT({
secret: PRIVATE_KEY
}).unless({
path: ['/api/user/register','/api/user/login'] //⽩白名单,除了了这⾥里里写的地址,其他的URL都需要验证
}));
在app.js中的错误中间件定义token的处理
// error handler
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
// 这个需要根据⾃自⼰己的业务逻辑来处理理
res.status(401).send({code:-1,msg:'token验证失败'});
}else {
// 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);
res.render('error');
}
});
在路由接口中可以使用req.user拿到token解密的值
路由页面如下
var express = require('express');
var router = express.Router();
var querySql = require("../db/index");
// md5加密key和方法
var {key} = require('../utils/store');
var {md5} = require("../utils/index")
// jwt生成token
var {PRIVITE_KEY,EXPIRESD} = require("../utils/store")
const jwt = require("jsonwebtoken");
// 登录接口
router.post("/login",async (req,res,next) => {
try {
// 对应前台的传参
let {username,password} = req.body;
// 跟数据库对应,看是否存在当前用户
password = md5(`${password}${key}`);
let result = await querySql("select * from user where username = ? and password = ?",[username,password]);
if(result && result.length != 0){
// 数据库有当前用户时返回token
let token = jwt.sign({username},PRIVITE_KEY,{expiresIn:EXPIRESD});
res.send({
code:0,
msg:"登录成功",
token:token
})
}else {
res.send({
code:-1,
msg:"用户名或者密码错误"
})
}
} catch (error) {
// p抛出异常并交由错误中间件处理
console.log(error);
next(error);
}
})
// 注册接口
router.post('/register', async (req, res, next)=>{
let {
username,
password,
nickname
} = req.body;
try {
// 查询当前用户名在不在数据库中(使用async方法后必须使用await方法才有值返回,不然返回promise对象)
let user = await querySql("select * from user where username = ?", [username]);
// 存在res即是数据库中有数据
if (user && user.length != 0) {
res.send({
code: -1,
msg: "用户已注册"
})
} else {
// 对密码进行加密
password = md5(`${password}${key}`);
// async 和 await 向数据库插入数据
await querySql("insert into user(username,password,nickname) values (?,?,?)", [username, password, nickname]);
res.send({
code: 0,
msg: "注册成功"
})
}
} catch (error) {
console.log(error)
next(error)
}
});
// 查询用户信息接口
router.get("/info",async (req,res,next)=>{
// 通过username获取用户信息
console.log(req.user)
let {username} = req.body;
try {
let userInfo = await querySql("select * from user where username = ?",[username]);
res.send({
code:0,
userInfo:userInfo
})
} catch (error) {
console.log(error);
next(error);
}
})
module.exports = router;
app.js写法如下
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require("cors");
// 使用express-jwt来进行token的解密和验证
const expressJWT = require('express-jwt');
var { PRIVITE_KEY } = require("./utils/store");
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users')
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 处理跨域
app.use(cors())
// 日志
app.use(logger('dev'));
// 使用post请求
app.use(express.json());
app.use(express.urlencoded({
extended: false
}));
// 使用cookie
app.use(cookieParser());
// 访问静态资源目录
app.use(express.static(path.join(__dirname, 'public')));
// 校验token,获取headers⾥里里的Authorization的token,要写在路由加载之前,静态资源之后
app.use(expressJWT({
secret: PRIVITE_KEY
}).unless({
path: ['/api/user/register', '/api/user/login'] //⽩白名单,除了了这⾥里里写的地址,其他的URL都需要验证
}));
// 使用路由
app.use('/', indexRouter);
app.use('/api/user', usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
// 这个需要根据⾃自⼰己的业务逻辑来处理理
res.status(401).send({code:-1,msg:'token验证失败'});
}else {
// 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);
res.render('error');
}
});
module.exports = app;