Vue项目中存储与使用后端传递过来的token
本文详细记录了在Vue项目中如何存储和使用后端传递的token。后端通过express-jwt中间件验证token,前端在登录时将token存入localStorage。文章重点讲解了如何利用Vue Router的beforeEach实现路由守卫,以及通过Axios请求和响应拦截器处理token过期导致的401状态码(实际为0)问题,确保用户自动跳转登录页。
前言
以往通常仅在Postman中进行Token验证测试,本文将记录在真实Vue项目中存储和使用Token的具体流程。
后端关于token的设置
在app.js中配置Token验证逻辑。
const expressJWT = require('express-jwt')
const app = express();
const config = require('./config')
app.use(expressJWT({secret: config.jwtSecretKey}).unless({path: [/^\/api\/users/]}))
const testRouter = require('./routes/testToken')
app.use('/my', testRouter)
config文件中定义了密钥,此处省略具体代码。
unless配置指定了无需Token验证的路由,即以/api/users开头的链接除外。
使用的testToken.js模块如下:
const express = require('express');
const router = express.Router();
const test = require('../router_handler/testToken')
router.get('/current', test.test)
module.exports = router
采用模块化写法,实际路由处理函数位于/router_handler/testToken.js中,代码如下:
const db = require('../db/index');
exports.test = (req, res) => {
const sql = 'select * from users where id = ?'
db.query(sql, req.user.id, (err, results) => {
if(err) return res.send({status: 404, message: err})
if(results.length !== 1) return res.send({status: 404, messsage: '获取用户信息失败,需重新登录'})
res.json(results[0])
})
// res.send(req)
}
该函数主要用于获取用户信息,通过MySQL根据ID查询数据。
关键步骤:经过上述配置后,访问非/api/users开头的链接时均需验证Token。Token在用户登录时生成,具体实现在用户登录处理函数user.js中:
// 用户登录的处理函数
exports.login = (req, res) => {
const userinfo = req.body
const sql = 'select * from users where name = ?'
db.query(sql, userinfo.name, (err, results) => {
if(err) return res.send({status: 404, message: err.message})
if(results.length !== 1) return res.status(404).json('用户不存在!')
const compareResults = bcrypt.compareSync(userinfo.password, results[0].password)
if(!compareResults) return res.status(404).json('密码错误!')
const user = {
id: results[0].id,
name: results[0].name,
avatar: results[0].avatar,
identify: results[0].identify
}
const tokenStr = jwt.sign(user, config.jwtSecretKey, {expiresIn: '10h'})
res.json({
status:200,
message: '登录成功',
// result: results[0],
token: 'Bearer ' + tokenStr
})
})
}
省略无关代码,注意tokenStr变量即为存储的Token值,通过响应返回。
总结后端存储Token的流程:
- 编写登录函数,向页面响应Token字符串;
- 在入口文件(app.js)中设置需要提供Token的路由,并提供解析Token字符串的密钥;
- 编写对应的路由函数,处理请求。
至此,后端关键要点已阐述完毕,接下来进入前端Token的存储部分。
前端页面取用token
前端在登录时应存储后端响应的Token,以实现路由守卫和免登录功能。
token存储
通过Ajax请求路由地址,获取res.data中的Token字符串,并存储至浏览器中。步骤和写法相对固定。
代码编写于Login.vue中,如下:
methods: {
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.$axios
.post("/users/login", this.loginUser)
.then(res => {
// console.log(res)
//token
const { token } = res.data
localStorage.setItem("eleToken", token)
this.$router.push("/index");
});
} else {
console.log("error submit!!");
return false;
}
});
}
}
const { token } = res.data通过解构赋值方式从响应数据中提取Token。
localStorage.setItem("eleToken", token)将Token存储至浏览器本地存储。

前端使用token实现路由守卫
后端代码中的unless相当于路由守卫,但前端也需实现此功能,否则无需登录即可访问网站内容,这显然不合理。
前端实现代码如下,编写于router.js中:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from './views/Index.vue'
import Register from './views/Register.vue'
import NotFound from './views/404.vue'
import Login from './views/Login.vue'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{ path: '*', name: '/404', component: NotFound },
{ path: '/', redirect: '/index' },
{ path: '/register', name: 'register', component: Register },
{ path: '/index', name: 'index', component: Index },
{ path: '/login', name: 'login', component: Login },
]
})
// 路由守卫
router.beforeEach((to, from, next) => {
const isLogin = localStorage.eleToken ? true: false
if(to.path == '/login' || to.path == '/register'){
next()
}else {
isLogin ? next() : next('/login')
}
})
export default router
关注路由守卫部分的代码逻辑。
使用Vue Router中的beforeEach函数。
具体逻辑如下:
- 定义isLogin(布尔值),若浏览器localStorage中存在eleToken对象,则值为true,否则为false;
- 确定无需拦截的路由:to.path == '/login' || to.path == '/register',即登录和注册页面直接放行,调用next();
- 对于被拦截的路由,判断isLogin是否为true,若是则说明已登录且有Token,直接放行;若为false,则跳转至登录路由。
请求拦截和响应拦截
还需解决Token过期判断问题。后端设置Token有效期为10小时,过期后应重新登录。
此处代码编写于单独的http.js文件中,先展示代码:
import axios from "axios";
import { Message, Loading } from 'element-ui';
import router from "./router"
let loading;
function startLoading(){
loading = Loading.service({
lock: true,
text: '数据加载中',
background: 'rgba(0,0,0,0.7)'
})
}
function endLoading(){
loading.close();
}
// 请求拦截
axios.interceptors.request.use(config => {
startLoading();
if(localStorage.eleToken){
// 设置统一的请求头
config.headers.Authorization = localStorage.eleToken
}
return config
}, error => {
return Promise.reject(error)
})
//响应拦截
axios.interceptors.response.use(response => {
endLoading();
return response
}, error => {
// 错误提醒
endLoading();
Message.error(error.response.data)
// 获取错误状态码
const {status} = error.response
if(status == 401){
Message.error("token失效,请重新登录")
localStorage.removeItem('eleToken')
router.push('/login')
}
return Promise.reject(error)
})
export default axios
关注后续的请求拦截和响应拦截逻辑。
分为两步:
请求拦截:当发送请求时,判断localStorage中是否存储了eleToken,若有则将其写入请求头;响应拦截:当Token过期时,页面会响应401错误状态码,此时需清除过期Token并跳转至登录页面。
注意,此处有一个坑,博主耗费一下午才解决,原以为:
页面会响应一个401的错误状态码
是正确的,但测试发现Token过期后并未跳转至登录页。打印status后发现该值等于0,因此响应拦截的正确写法应为:
//响应拦截
axios.interceptors.response.use(response => {
endLoading();
return response
}, error => {
// 错误提醒
endLoading();
Message.error(error.response.data)
console.log(error.response)
// 获取错误状态码
const {status} = error.response
console.log(status)
if(status === 0){
Message.error("token失效,请重新登录")
localStorage.removeItem('eleToken')
// console.log(error)
router.push('/login')
}
return Promise.reject(error)
})
修正状态码判断后,跳转功能恢复正常。
至此,前后端Token的使用流程已顺畅运行。
总结
本文介绍了Vue项目中存储与使用后端传递Token的方法,更多相关内容可搜索本站往期文章或继续浏览后续文章,希望大家支持本站!
NestJS 是什么?与 Express、Koa 的核心区别及选型建议
2026-11-05 13:46:41
生产环境升级 Node.js 的注意事项与兼容性测试策略
2026-11-05 09:19:24
nvm 常用命令详解:怎么平滑切换和升级 Node.js 版本
2026-11-04 09:02:34
JavaScript和JSP的根本区别:运行环境与执行机制解析
2026-11-03 23:30:18
使用nvm卸载指定版本Node.js并切换默认环境
2026-11-03 23:09:26
