后端部分
安装
npm install jsonwebtoken
npm install express-jwt
使用
const jwt = require('jsonwebtoken') // 生成 JWT 字符串
const {
expressjwt } = require('express-jwt')// 将客户端发送来的 JWT 字符串解析成 JSON
const app = express()
const secret = 'forexample' // 密钥用于加密
const expiresIn = {
expiresIn: "15 days" } // 设置token过期时间
const whiteList = ['/login', '/register'] // 白名单,没有token也放行
// 生成token
// info是payload是需要存入token的信息
function createToken (info) {
let token = jwt.sign(
info, secret, expiresIn)
return token
}
// 校验token
app.use(expressjwt({
secret: secret,
algorithms: ['HS256'], // 加密算法,HS256是默认值
// 设置为true表示校验,false表示不校验,默认值为true
// credentialsRequired: true,
}).unless({
path: whiteList })) // 对白名单里的路径直接放行
// 拦截器
app.use((err, req, res, next) => {
// 如果错误是由 token 解析失败导致的
if (err.name === 'UnauthorizedError') {
return res.send({
status: 401,
message: '无效的token'
})
}
res.send({
status: 500,
message: '未知的错误'
})
})
/**
* 实现登录验证功能
*/
app.post('/login', function (req, res) {
......
// 生成 JWT 字符串,根据需要传入参数,注意别将用户密码加密到 Token 中
let token = createToken({
userid: rows[0].userid })
// 将token传给前端
res.send({
status: 200, message: '登录成功!', token: token })
})
前端部分
新建axios.js
import axios from "axios"
import router from "../router"
import {
Message, Loading } from "element-ui"
const service = axios.create({
// baseURL: _baseURL,
timeout: 600000,
withCredentials: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
}
})
......
// axios 请求处理超时处理
service.interceptors.response.use(
function (response) {
if (response.data.status == 401) {
// token过期,需要登录
console.log("token过期")
Message({
message: "token已过期,请重新登录",
type: "warning",
})
localStorage.removeItem("token")
router.push("/").catch(err => {
}) // catch解决路由重复点击报错
return false
}
return response
},
(err) => {
if (err.message === "Network Error") {
Message.error("网络异常,请检查网络连接情况")
}
return Promise.reject(err.response.data)
}
)
export default service
新建index.js
import axios from './axios' // 上面的axios.js
import qs from "qs" // axios默认请求头是application/x-www-form-urlencoded,qs用于提交表单
export default {
...
getTop10: () => {
return axios.get('/api/getTop10', {
headers: {
Authorization: "Bearer " + localStorage.getItem("token") }, // 将token传给后端
})
},
...
}
路由守卫
//路由守卫
router.beforeEach((to, from, next) => {
// console.log("to", to)
// 目标路由不是登录页,并且还需要token验证,还没有token,那就直接给返回到登录页
if (to.name !== 'login' && to.meta.authRequired && !localStorage.getItem('token')) {
Message({
message: "请先登录",
type: "warning",
})
next({
name: 'login' })
} else {
// 放行
next()
}
})
to.meta.authRequired
是写router时自己设定的