网址:https://www.jianshu.com/p/58abb716b5dc/
具体概念参考上面链接
Token验证的基本流程
1.服务端收到请求,去验证用户名与密码
2.验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
3.客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
4.客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
5.服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
JWT标准的Token有如下三个部分
header (头部)
payload (数据)
signature (签名)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInVzZXJfaWQiOjEsImlhdCI6MTU5NDI2MjQ5NSwiZXhwIjoxNTk0MzQ4ODk1fQ.1MJ_MAFgpBjOjpggj69Xz8F_evBcMAenRK_7a8fdVrc
安装
//生成token与验证
1.jsonwebtoken
npm install jsonwebtoken --save
* 生成token的方法 sign
* 验证token的方法 verify
2.express-jwt
npm install express-jwt --save
* 验证token是否过期并规定那些路由不需要验证 express-jwt({})
定义生成token和获取token的函数
/token/token.js
var jwt = require('jsonwebtoken');
var jwtScrect = 'zgs_first_token'; //签名
//登录接口 生成token的方法
var setToken = function (user_name, user_id) {
return new Promise((resolve, reject) => {
//expiresln 设置token过期的时间
//{ user_name: user_name, user_id: user_id } 传入需要解析的值( 一般为用户名,用户id 等)
const token = jwt.sign({ user_name: user_name, user_id: user_id }, jwtScrect, { expiresIn: '24h' });
// const token = jwt.sign({ user_name: user_name, user_id: user_id }, jwtScrect, { expiresIn: '10s' });
resolve(token)
})
}
//各个接口需要验证token的方法
var getToken = function (token) {
return new Promise((resolve, reject) => {
if (!token) {
console.log('token是空的')
reject({
error: 'token 是空的'
})
}
else {
var info = jwt.verify(token.split(' ')[1], jwtScrect);
resolve(info); //解析返回的值(sign 传入的值)
}
})
}
module.exports = {
setToken,
getToken
}
解析token,验证token
app.js
const express = require("express")
const app = express()
const path = require("path")
const usersRouter = require("./router/usersRouter")
//引入插件
var vertoken = require('./token/token')
var expressJwt = require('express-jwt')
app.use(express.json())
//设置托管静态目录; 项目根目录+ public.可直接访问public文件下的文件eg:http://localhost:3000/images/url.jpg
app.use(express.static(path.join(__dirname, 'public')));
//解析token获取用户信息
app.use(function (req, res, next) {
var token = req.headers['authorization'];
if (token == undefined) {
next();
} else {
vertoken.getToken(token).then((data) => {
req.data = data;
next();
}).catch((error) => {
next();
})
}
});
//验证token是否过期并规定那些路由不需要验证
app.use(expressJwt({
secret: 'zgs_first_token',
// 算法
algorithms: ['HS256']
}).unless({
path: ['/user/login', '/register','/'] //不需要验证的接口名称
}))
//token失效返回信息
app.use(function (err, req, res, next) {
if (err.status == 401) {
return res.status(401).send('token失效')
//可以设置返回json 形式 res.json({message:'token失效'})
}
})
app.use('/user', usersRouter);
app.listen(3000, () => {
console.log('服务开启');
})
登录接口和需验证接口
/router/usersRouter.js
const express = require("express")
const router = express.Router()
//引入token
var vertoken = require('../token/token')
/* user login 用户登录*/
router.post('/login', function (req, res) {
console.log(req.body);
//获取参数
const params = [];
params[0] = req.body.user_name
params[1] = req.body.password
//调用生成token的方法
vertoken.setToken(...params).then(token => {
console.log(4);
res.json({
code: 200,
message: '登录成功',
token: token
//前端获取token后存储在localStroage中,
//**调用接口时 设置axios(ajax)请求头Authorization的格式为`Bearer ` +token
})
})
});
// 获取用户接口信息
router.get("/",(req,res)=>{
//获取token中解析的数据
console.log(req.data);
res.send({
code: 0,
msg: '数据 '
})
})
module.exports = router
前端请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p><button id="login">登录</button></p>
<p><button id="getData">调接口</button></p>
<script src="./js/axios.js"></script>
<script>
login.onclick = function () {
axios.post("/user/login", {
user_name: 'wf',
password: '123'
})
.then(res => {
localStorage.setItem("token", res.data.token)
})
}
getData.onclick = function () {
axios.get("/user", {
headers: {
authorization: 'Bearer ' + localStorage.getItem("token")
}
})
.then(res => {
console.log(res.data);
})
}
</script>
</body>
</html>
网友评论