定義:token也稱為令牌,作為計(jì)算機(jī)的臨時(shí)標(biāo)識(shí)符,具體作用與cookie類似。cookie的作用參見 Cookie&Session的使用
token與cookie對(duì)比
- 共同點(diǎn):帶一個(gè)標(biāo)識(shí)讓服務(wù)器認(rèn)識(shí),通過請(qǐng)求頭告知服務(wù)器,服務(wù)器通過響應(yīng)頭給瀏覽器
- 不同點(diǎn):cookie服務(wù)端從存到用都是全自動(dòng),token是全手動(dòng)
- 應(yīng)用場景:token大部分用于移動(dòng)端
舉個(gè)例子——在koa中使用token
需求:使用token的方式,來替代cookie,進(jìn)入頁面A得到token,進(jìn)入頁面B時(shí)通過token得到用戶數(shù)據(jù)
實(shí)現(xiàn):
1. 下載依賴包koa-jwt jsonwebtoken
2. 登陸后生成token(jsonwebtoken.sign),響應(yīng)頭給客戶端
3. 其它需要身份的頁面直接ctx.state.user獲取加密的數(shù)據(jù)
代碼實(shí)現(xiàn):
const Koa = require("koa");
const Router = require("koa-router");
const jwt = require("koa-jwt");
const jsonwebtoken = require("jsonwebtoken");
const app = new Koa();
const router = new Router();
router.get("/gettoken", (ctx, next) => {
//模擬數(shù)據(jù)
let user = {userId: 3, name: 'jack'};
//使用jsonwebtoken加密
let token = jsonwebtoken.sign(user, 'shhhhh');
//響應(yīng)token
ctx.response.set('my-token', token);
ctx.body = "token寫回成功";
})
.get("/showInfo", (ctx, next) => {
//jwt中為了獲取之前加密的數(shù)據(jù),可以使用ctx.state.user來拿
console.log(ctx.state.user);
ctx.body = "登錄成功"
})
//配置靜態(tài)文件路徑
app.use(require("koa-static")("./"));
//加載到中間件中
//unless 代表排除哪些不進(jìn)行token驗(yàn)證
//passthrough 代表是否最終都顯示頁面(通常設(shè)置為true,token的目的是記住用戶狀態(tài))
app.use(jwt({secret: 'shhhhh', passthrough: true}).unless({path: ["/gettoken"]}));
app.use(router.routes())
.use(router.allowedMethods());
app.listen(8888, ()=>{
console.log("The server is running...")
});
效果:
- 客戶端訪問http://localhost:8888/gettoken時(shí)則會(huì)寫入token值
客戶端請(qǐng)求A頁面 - 客戶端訪問http://localhost:8888/showInfo并在請(qǐng)求頭上攜帶
authorization:bearer tokenValue時(shí),可獲取用戶數(shù)據(jù)
請(qǐng)求B頁面
以上為使用postman發(fā)起請(qǐng)求,那么如何在前臺(tái)發(fā)送請(qǐng)求呢
思路:
1.為了代碼簡潔,可以配置全局默認(rèn)行為;$.ajaxSetup
2. 請(qǐng)求前,檢查是否有token,加入請(qǐng)求頭;
3. 登陸后,獲取響應(yīng)頭token保存
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<button type="button" name="button" onclick="doLogin()">登錄</button>
<button type="button" name="button" onclick="showMessage()">獲取</button>
<script type="text/javascript">
//全局token值
let token;
//配置全局默認(rèn)行為
$.ajaxSetup({
complete: xhr => {
//從響應(yīng)頭中獲取my-token值并保存到全局變量中
token = xhr.getResponseHeader('my-token');
},
//在發(fā)起請(qǐng)求之前添加請(qǐng)求頭
beforeSend: xhr => {
if(token) {
xhr.setRequestHeader('authorization', `bearer ${token}`);
}
}
});
function doLogin() {
$.ajax({
url: "/gettoken",
type: "get"
})
}
function showMessage() {
$.ajax({
url: "/showInfo",
method: "get",
success: function (res) {
alert(res);
}
})
}
</script>
</body>
</html>
效果:

通過ajax請(qǐng)求B頁面

