使用jsonwebtoken生成token與驗(yàn)證是否過期
場景
我們可以使用 cookie,session,token 來做鑒權(quán)。
下面我們來看一下,
如何使用 token 來做鑒權(quán)
jwt.sign 的簡單介紹
npm install jsonwebtoken 下載
使用 jsonwebtoken 生成token的基本語法。jwt.sign(payload, secretOrPrivateKey, [options, callback])
第1個(gè)參數(shù) payload:可以是表示有效 JSON 的對象文本、緩沖區(qū),字符串。
需要注意的是:如果不是緩沖區(qū)或字符串,使用 JSON.stringify下面我們使用對象文本,就不需要使用 JSON.stringify。第2個(gè)參數(shù) secretOrPrivateKey: 是一個(gè)字符串(utf-8編碼)、緩沖區(qū)、對象。
就是說是加密數(shù)據(jù)。
options:包含的其他選項(xiàng),如過期時(shí)間,
它的選項(xiàng)有:expiresIn 過期時(shí)間,如果是數(shù)字,單位就是秒。algorithm: HS256 (默認(rèn)的算法)
callback:回調(diào)函數(shù),包含返回來的錯(cuò)誤
使用 jsonwebtoken 生成token
// 生成的token。 expiresIn 數(shù)值單位默認(rèn)是秒s//expiresIn也可以添加為 expiresIn:'10h' | '10d'let createToken = jwt.sign({ ?data: 'jiamideshuju'}, 'lingpai', { expiresIn: 3 });// ?expiresIn: 3 表示的是有效時(shí)間是3s。console.log('生成的token', createToken)

查看生成的token是否過期
// 生成的token。let createToken = jwt.sign({ ?data: 'jiamideshuju'}, 'lingpai', { expiresIn: 3 });console.log('生成的token', createToken)setTimeout(()=>{ ?// 查看token是否過期
?var decoded = jwt.verify(createToken, 'lingpai') ?console.log('4s后token是否過期', decoded)
},4000)

封裝生成token與驗(yàn)證token是否過期
utils/createTokenCheck.js文件// 引入 jsonwebtokenlet jwt = require('jsonwebtoken');let lingpai = 'weislingpai'const createTokenCheck = { ?// 生成的token。并設(shè)置過期時(shí)間
?getToken(jiamiData,expiresIn=3){ ? ?return jwt.sign({ ? ? ?data: jiamiData
? ?}, lingpai, { expiresIn: expiresIn })
?}, ?// 檢查token是否過期
?verify(token){ ? ?try { ? ? return jwt.verify(token, lingpai)
? ?} catch (error) { ? ? ?// 如果報(bào)錯(cuò)返回false.[因?yàn)閠oken有可能過期,就會(huì)報(bào)錯(cuò)]
? ? ?console.log('error:', error) ? ? ?return false
? ?}
?}
}// 暴露出去,其他地方調(diào)用就行module.exports = createTokenCheck
app.js文件調(diào)用const createTokenCheck =require('./utils/createTokenCheck')let token= createTokenCheck.getToken('zhangsan',2)console.log('不會(huì)過期', token)setTimeout(() => { ?let data=createTokenCheck.verify(token) ?console.log('過期返回false', data)
}, 3000);

登錄驗(yàn)證
前端代碼<template>
?<div>
? ?<h2>登錄頁</h2>
? ?<form action="">
? ? ?用戶名:<input type="text" v-model="userInfo.user"> <br>
? ? ?密 ?碼:<input type="password" v-model="userInfo.password"><br>
? ? ?<button @click="handlerLogin">登錄</button>
? ?</form>
?</div></template><script setup lang="ts">import {reactive} from 'vue'import axios from 'axios'const userInfo = reactive({ ?user:'', ?password:''})const handlerLogin=()=>{
?axios.post('http://127.0.0.1:3000/login', { ? ?user:userInfo.user, ? ?password: userInfo.password,
?}).then(res => { ? ? ?console.log(res);
?}).catch(error => { ? ? ?console.log(error);
?});
}</script>
app.jsapp.post('/login', ?function(req, res) { ?console.log('req', req.body) ?//通過req.body接收傳遞的參數(shù)
?let { user, password } = req.body
?// 我們假設(shè)用戶是這樣就會(huì)成功
?if(user==='zhangsan'&& password==='123'){ ? ?// 生成token 過期時(shí)間設(shè)置為10s
? ?let token= createTokenCheck.getToken('zhangsan',10) ? ?// 發(fā)送token
? ?res.send({ ? ? ?code: 'ok', ? ? ?msg:'登錄成功', ? ? ?token:token
? ?});
?}else{
? ?res.send({ ? ? ?code: 'fail', ? ? ?msg: '登錄失敗',
? ?});
?}
})


無法加載響應(yīng)數(shù)據(jù): No data found for resource with given identifier
我們現(xiàn)在需要下載 cors
npm i cors
然后在app.js中引入
const cors = require('cors')// 放置在路由的前面app.use(cors())
'req.body' as it is undefined.
//放置在路由的前面app.use(express.json()); ?

前端接口攜帶token
攜帶token
<template>
?<div>
? ?<h1 class="h1">我是test文件</h1>
?</div></template><script setup lang="ts">import axios from 'axios'const handlerLogin=()=>{
?axios.post('http://127.0.0.1:3000/list',{},{ ? ?headers:{ ? ? ?authorization: localStorage.getItem('token')
? ?}
?}).then(res => { ? ?console.log(res) ? ?console.log(res);
?}).catch(error => { ? ? ?console.log(error);
?});
}handlerLogin()</script>
aap.js代碼const createTokenCheck =require('./utils/createTokenCheck')// 處理跨域const cors = require('cors')const express = require('express')const app = express()
app.use(cors())// 處理 ?'req.body' as it is undefined.app.use(express.json()); ?
const port = 3000app.get('/', (req, res) => res.send('Hello World!'))
app.post('/login', ?function(req, res) { ?console.log('req', req.body) ?//通過req.body接收傳遞的參數(shù)
?let { user, password } = req.body
?// 我們假設(shè)用戶是這樣就會(huì)成功
?if(user==='zhangsan'&& password==='123'){ ? ?// 生成token 過期時(shí)間設(shè)置為10s
? ?let token= createTokenCheck.getToken('zhangsan',10) ? ?// 發(fā)送token
? ?res.send({ ? ? ?code: 'ok', ? ? ?msg:'登錄成功', ? ? ?token:token
? ?});
?}else{
? ?res.send({ ? ? ?code: 'fail', ? ? ?msg: '登錄失敗',
? ?});
?}
})
app.post('/list', ?(req, res) =>{ ?let getToken = (req.headers && ?req.headers.authorization) || ''
?if(getToken){ ? ?// 檢查token是否過期
? ?if(createTokenCheck.verify(getToken)){
? ? ?res.send({ ? ? ? ?code: 'ok', ? ? ? ?list: [
? ? ? ? ?{name:'張三',grade:98, status:'通過考試'},
? ? ? ? ?{name:'李四',grade:58, status:'未通過考試'},
? ? ? ? ?{name:'王五',grade:78, status:'通過考試'}
? ? ? ?]
? ? ?});
? ?}else{
? ? ?res.send({ ? ? ? ?code: 'fail', ? ? ? ?list: [], ? ? ? ?msg:'token過期'
? ? ?});
? ?}
?}else{
? ?res.send({ ? ? ?code: 'fail', ? ? ?list: [], ? ? ?msg:'請攜帶token'
? ?});
?}
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

