Token
在計算機身份認證中是令牌(臨時)的意思,在詞法分析中是標記的意思。一般我們所說的的 token 大多是指用於身份驗證的 token
Token的特點
- 隨機性
- 不可預測性
- 時效性
- 無狀態、可擴充套件
- 跨域
基於Token的身份驗證場景
- 客戶端使用使用者名稱和密碼請求登入
- 服務端收到請求,驗證登入是否成功
- 驗證成功後,服務端會返回一個 Token 給客戶端,反之,返回身份驗證失敗的資訊
- 客戶端收到 Token 後把 Token 用一種方式(cookie/localstorage/sessionstorage/其他)儲存起來
- 客戶端每次發起請求時都選哦將 Token 發給服務端
- 服務端收到請求後,驗證Token的合法性,合法就返回客戶端所需資料,反之,返回驗證失敗的資訊
Token 身份驗證實現 —— jsonwebtoken
先安裝第三方模組 jsonwebtoken npm install jsonwebtoken
const express = require(`express`)
const path = require(`path`)
const app = express();
const bodyParser = require(`body-parser`);
const jwt = require(`jsonwebtoken`);
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, `/`)));
app.all(`*`, function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Auth, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",` 3.2.1`)
if(req.method=="OPTIONS") {
res.sendStatus(200);/*讓options請求快速返回*/
} else{
next();
}
});
app.get(`/createtoken`, (request, response) => {
//要生成 token 的主題資訊
let user = {
username: `admin`,
}
//這是加密的 key(金鑰)
let secret = `dktoken`;
//生成 Token
let token = jwt.sign(user, secret, {
`expiresIn`: 60*60*24 // 設定過期時間, 24 小時
})
response.send({status: true, token});
})
app.post(`/verifytoken`, (request, response) => {
//這是加密的 key(金鑰),和生成 token 時的必須一樣
let secret = `dktoken`;
let token = request.headers[`auth`];
if(!token){
response.send({status: false, message: `token不能為空`});
}
jwt.verify(token, secret, (error, result) => {
if(error){
response.send({status: false});
} else {
response.send({status: true, data: result});
}
})
})
app.listen(88)
前端 ajax 請求時在請求頭中包含 Token
ajax 請求之 jQuery 篇
$.ajax({
url: `verifytoken`,
type: `post`,
headers: {"auth": `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTIzNTQwNjY5LCJleHAiOjE1MjM2MjcwNjl9.ddkS5XEiMzvNQsk9UlMPhyxPSq5S_oh3Nq19eIm9AJU`},
success: function(res){
console.log(res)
}
})
ajax 請求之 XMLHttpRequest 篇
var xhr = new XMLHttpRequest();
xhr.open("POST","verifytoken");
xhr.setRequestHeader(`auth`, `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTIzNTQwNjY5LCJleHAiOjE1MjM2MjcwNjl9.ddkS5XEiMzvNQsk9UlMPhyxPSq5S_oh3Nq19eIm9AJU`);
xhr.send();
ajax 請求之 axios 篇
import axios from `axios`
axios({
url: url,
params: _params || {},
headers: {auth: window.sessionStorage.getItem(`dktoken`)}
}).then(res => {
if(!res.data.status && res.data.error == "unauthorized"){
router.push(`login`);
return false;
}
resolve(res)
}).catch(error => {
reject(error)
})
ajax 請求之 superagent 篇
import http from `superagent`
http.post(getUrl(path))
.set(`Content-Type`, `application/x-www-form-urlencoded; charset=UTF-8`)
.set(`auth`, window.localStorage.getItem(`access_token`))
.end((err, res) => {});