示例为node,koa服务端
下载对应依赖包
npm install jsonwebtoken --save
用法
const jwt = require('jsonwebtoken')
const secret = 'ZHX_TOKEN'
//创建token
let token = jwt.sign(obj,secret,opt)
//解码token
jwt.verify(token,secret,callback)
在用户登录成功时,创建token
async login(ctx, next) {
await Passport.authenticate('local', async function (err, user, info) {
if (err) {
ctx.body = {
errorCode: -1,
message: err
}
} else {
if (user) {
await ctx.login(user)//登录成功
//id 用户id
let playLoad = { userId: user.id }
let token = jwt.sign(playLoad, secret, { expiresIn: 60 * 60 * 1 }) // 一小时后过期
ctx.body = {
errorCode: 0,
message: '登录成功',
token: token,
user
}
} else {
ctx.body = {
errorCode: 1,
message: info
}
}
}
})(ctx, next)
anguler为例
放在cookie中需要提前下载cookie服务
npm install ngx-cookie-service --save
//引入服务
constructor(public cookieService:CookieService) {}
//设置
this.cookieService.set('access-token',resultData.token)
localStorage
localStorage.setItem('access-token',resultData.token)
angular如何在请求头中设置token呢?
方法一:通过自定义http请求方法
登录成功后,设置请求头
this.canActivateService.login(this.userInfo.username, this.userInfo.password).subscribe(resultData => {
if (resultData.errorCode === 0) {
this.cookieService.set('access-token', resultData.token)
this.http.headerOption.headers = new HttpHeaders({
"Content-Type": 'application/json',
'Authorization': resultData.token
});
this.canActivateService.isLogin = true;
this.userService.setUserInfo(resultData.user)
this.router.navigate(['/index']).then();
} else {
this.message.create('error', resultData.message)
}
})
简易封装的http请求
headerOption = {headers: new HttpHeaders({"Content-Type": 'application/json', 'Authorization': ''})}
constructor(public httpClient: HttpClient) {
}
get(url: string) {
return new Observable(subscriber => {
this.httpClient.get<any>(url, this.headerOption).subscribe(res => {
if (res.errorCode === 0) {
subscriber.next(res)
} else if (res.errorCode === 50014) { //token过期
this.cookieService.delete('access-token')
this.router.navigate(['/login']).then(); //在过期后会跳到登录页
} else {
subscriber.error(res)
}
})
})
}
方法二:通过对请求进行拦截,然后进行设置
拦截器放在另一篇讲
5.服务端收到请求后,会对token进行校验,如果校验通过后,才会进行业务请求的处理,如果token超时,则应该返回到用户登录页面重新进行登录
const jwt = require("jsonwebtoken");
const secret = 'ZHX_TOKEN'
const filterCheckUrlList = ['/login', '/user/register']
async function check(ctx, next) {
let url = ctx.request.url;
//不用检查
if (filterCheckUrlList.indexOf(url) !== -1) await next();
else {
let token = ctx.request.headers["authorization"];
jwt.verify(token, secret, async function (err, decode) {
if (err) { // 时间失效的时候/ 伪造的token
ctx.body = {
status: 50014,
message: 'token 已过期'
};
} else {
await next();
}
})
}
}
module.exports = check
中间件
const check = require('./utils/check')
app.use(check)
用户退出系统时流程
客户端发送登出请求,服务端通过,客户端对cookie或localstoage中token进行销毁
this.cookieService.delete('access-token')
如何对token进行刷新呢?
1.有两个token 一个时间长一个时间短。当两个都过期之后跳转到登录重新申请token,若时间长的未过期时,则利用时间长的去重新申请短的token,这种是用户无感
2.每进行一次操作,计算时间就重新计量