在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般我们所说的的token大多是指用于身份验证的token
我们需要每次都知道当前请求的人是谁,但是又不想每次都让他提交用户名和密码,这时就需要有一个等同于用户名密码也能够标识用户身份的东西,即—token.
· 随机性:每次的token都是不一样的
· 不可预测性:没有规律,无法预测
· 时效性: 可以设置token的有效时间
· 无状态、可扩展:由于只是一个算法,扩展起来非常方便
生成Token的解决方案有许多,常用的一种就是 Json Web Tokens .
JWT标准的Tokens由三部分组成
加粗样式这三部分中间使用 " . " 分隔开,并且都会使用Base64编码方式编码,如下:
eyJhbGc6IkpXVCJ9.eyJpc3MiOiJCIsImVzg5NTU0NDUiLCJuYW1lnVlfQ.SwyHTf8AqKYMAJc
客户端收到这个 Token 以后把它存储下来,下回向服务端发送请求的时候就带着这个 Token 。服务端收到这个 Token ,然后进行验证,通过以后就会返回给客户端想要的资源。
header
header 部分主要是两部分内容,一个是 Token 的类型,另一个是使用的算法,比如下面类型就是 JWT,使用的算法是 Hash256。
{
“typ”: “JWT”,
“alg”: “HS256”
}
payload
Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。下面是标准字段:
· iss:Issuer,发行者
· sub:Subject,主题
· aud:Audience,观众
· exp:Expiration time,过期时间
· nbf:Not before
· iat:Issued at,发行时间
· jti:JWT ID
比如下面
{
“iss”: “ninghao.net”,
“exp”: “1438955445”,
“name”: “wanghao”,
“admin”: true
}
signature
JWT 的最后一部分是 Signature ,这部分先是拼接 Base64 编码的 header.payload ,再用不可逆的Hamc加密算法加密,加密时使用一个密钥,这个密钥服务端保存,生成signature。
最后组合token,如下
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.
SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
使用nodejs实现jwt验证
安装jsw模块
cnpm install jsonwebtoken -S
在js文件中引用jsw模块
var jwt = require("jsonwebtoken");
生成Token
var jwt = require(“jsonwebtoken”);
var content = { msg: ‘{“username”:“张三”}’ }; // 要生成token的主题信息【这里可以包含用户的一些相关信息,content需要为一个对象,否则有可能会报错】
var secretOrPrivateKey = “mouchun.com” // 这是加密的key(密钥或私钥)
var token = jwt.sign(content, secretOrPrivateKey, {
expiresIn: 60 * 15 // 24小时过期,以s作为单位
});
console.log(“token :” + token);
校验Token
var token = "获取的前端传来的token";//rq.body.token || rq.query.token || rq.headers["x-access-token"]; // 可以从body或query或者header中获取token
var token=“eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtc2ciOiJ7XCJ1c2VybmFtZVwiOlwi5byg5LiJXCJ9IiwiaWF0IjoxNTY2ODI4MTkyLCJleHAiOjE1NjY4MjkwOTJ9.gOp5y5otOd-YG6lrwQhycwaS4PM95nt3qTYSRtPkthc”;
var secretOrPrivateKey = “mouchun.com” // 这是加密的key(密钥或私钥)
jwt.verify(token, secretOrPrivateKey, function (err, decode) {
if (err) { // 当token过期,或这是一个伪造的token,或这是无效的token时会触发此逻辑
console.log(err);
} else {
console.log(decode.msg); // {“username”:“张三”}
}
})
Token生成与校验函数的封装
//生成和效验token
var jwt = require(“jsonwebtoken”);
var tokenObj={
//生成
createToken:function(cont,time){
var content={msg:cont}
var secretOrPrivateKey = ‘mouchun’ // 这是加密的key(密钥或私钥)
var token = jwt.sign(content, secretOrPrivateKey, {
expiresIn: time // 24小时过期,以秒作为单位
})
return token;
},
//效验
checkToken:function(token,fn){
var secretOrPrivateKey = ‘mouchun’ // 这是加密的key(密钥或私钥)
jwt.verify(token, secretOrPrivateKey, function (err, decode) {
if (err) { // 当token过期,或这是一个伪造的token,或这是无效的token时会触发此逻辑
console.log(err)
fn(false);
} else {
console.log(decode.msg);
fn(true);
}
})
}
}
//生成
var mytoken=tokenObj.createToken(“张三”,60*60);
console.log(mytoken);
//效验
tokenObj.checkToken(mytoken,function(){
console.log(“效验成功,删除数据…”)
})
module.exports.tokenObj=tokenObj;
checkedToken.js调用封装效验token
let tokenObj=require("./token.js");
var mytoken=tokenObj.tokenObj.createToken(“张三”,60*60);
tokenObj.tokenObj.checkToken(mytoken,function(){
console.log(“效验成功,删除数据…”)
})
登录验证token
1.登入成功后端返回token给前端
2.前端将拿到的token存入会话
3.在将本地会话token传入后端
4.后端效验token
5.python带上header头部验证
原生:
//2.发送请求类型(请求方式,请求url(后端接口数据),true(异步)或 false(同步))
xmlhttp.open(“get”,“http://10.1.0.79:8000/index/hot”,true);
//setRequestHeader() 来添加 HTTP 头
xmlhttp.setRequestHeader(“Authorization”, "Bearer "+sessionStorage.token1);
ajax: