Vue.js 实现用户登录状态持久化:从Token存储到前端路由守卫详解

Vue.js 实现用户登录状态持久化:从Token存储到前端路由守卫详解

在现代的前后端分离架构中,Vue.js因其灵活性和易用性而广受欢迎。然而,如何实现用户登录状态的持久化,确保用户在多次会话中保持登录状态,是一个常见且重要的课题。本文将深入探讨在Vue.js项目中如何通过Token存储和前端路由守卫来实现用户登录状态的持久化。

一、Token的基本概念与作用

什么是Token?

Token是用户登录成功后,服务器返回的一个身份认证令牌。它通常用于访问需要授权的API接口和校验页面权限。

Token的作用:

身份验证:确认用户身份,防止未授权访问。

会话管理:在无状态的HTTP协议中,通过Token来维持用户会话。

安全性:Token通常包含签名信息,难以伪造。

二、Token的存储方式

在Vue.js项目中,Token的存储方式主要有两种:本地存储和Vuex存储。

1. 本地存储

优点:

持久化:即使浏览器刷新,Token也不会丢失。

缺点:

非响应式:本地存储的数据不具备响应式特性,无法实时反映在Vue组件中。

2. Vuex存储

优点:

响应式:Vuex存储的数据是响应式的,能够实时反映在Vue组件中。

缺点:

非持久化:浏览器刷新后,Vuex中的数据会丢失。

解决方案:将Token同时存储在本地和Vuex中,前者解决持久化问题,后者实现响应式。

三、配置Vuex进行Token存储

1. 安装Vuex

npm install vuex@next --save

2. 创建Vuex存储

在src目录下创建store目录,并在其中创建index.js文件:

import { createStore } from 'vuex';

const store = createStore({

state: {

user: null, // 存储当前登录用户信息,包含token等数据

},

mutations: {

setUser(state, user) {

state.user = user;

localStorage.setItem('user', JSON.stringify(user)); // 同步存储到本地

},

clearUser(state) {

state.user = null;

localStorage.removeItem('user'); // 清除本地存储

}

},

actions: {

login({ commit }, user) {

commit('setUser', user);

},

logout({ commit }) {

commit('clearUser');

}

},

getters: {

isAuthenticated(state) {

return state.user !== null;

}

}

});

export default store;

3. 将Vuex注入到Vue实例中

在main.js中注入Vuex存储:

import { createApp } from 'vue';

import App from './App.vue';

import store from './store';

const app = createApp(App);

app.use(store);

app.mount('#app');

四、前端路由守卫配置

为了保护需要登录才能访问的页面,我们需要配置Vue Router的路由守卫。

1. 定义路由

在router/index.js中定义路由,并添加meta选项来标识需要登录的页面:

import { createRouter, createWebHistory } from 'vue-router';

import Home from '../views/Home.vue';

import Login from '../views/Login.vue';

import Dashboard from '../views/Dashboard.vue';

const routes = [

{

path: '/',

name: 'Home',

component: Home

},

{

path: '/login',

name: 'Login',

component: Login

},

{

path: '/dashboard',

name: 'Dashboard',

component: Dashboard,

meta: { requiresAuth: true } // 需要登录才能访问

}

];

const router = createRouter({

history: createWebHistory(process.env.BASE_URL),

routes

});

export default router;

2. 配置路由守卫

在router/index.js中添加全局前置守卫:

import store from '../store';

router.beforeEach((to, from, next) => {

if (to.matched.some(record => record.meta.requiresAuth)) {

if (store.getters.isAuthenticated) {

next(); // 已登录,放行

} else {

next('/login'); // 未登录,重定向到登录页面

}

} else {

next(); // 不需要登录,放行

}

});

五、登录逻辑与Token处理

1. 登录请求

在登录页面中,使用axios发送登录请求,并在登录成功后保存Token:

import axios from 'axios';

import { useStore } from 'vuex';

export default {

methods: {

async login() {

const store = useStore();

try {

const response = await axios.post('/api/login', {

username: this.username,

password: this.password

});

const { token } = response.data;

store.dispatch('login', { token });

this.$router.push('/dashboard');

} catch (error) {

console.error('登录失败', error);

}

}

}

};

2. 设置请求头

在main.js中设置axios的请求拦截器,将Token添加到请求头中:

import axios from 'axios';

import store from './store';

axios.interceptors.request.use(config => {

if (store.getters.isAuthenticated) {

config.headers.Authorization = `Bearer ${store.state.user.token}`;

}

return config;

}, error => {

return Promise.reject(error);

});

六、后端Token验证

在后端,使用JWT库来验证Token的有效性:

const jwt = require('jsonwebtoken');

const secretKey = 'your-secret-key';

app.use((req, res, next) => {

const token = req.headers.authorization?.split(' ')[1];

if (token) {

jwt.verify(token, secretKey, (err, decoded) => {

if (err) {

return res.status(401).json({ message: 'Token无效' });

}

req.user = decoded;

next();

});

} else {

return res.status(401).json({ message: '未提供Token' });

}

});

七、总结

通过本文的详细讲解,我们了解了在Vue.js项目中如何实现用户登录状态的持久化。主要包括以下几个方面:

Token的基本概念与作用:理解Token在身份验证和会话管理中的重要性。

Token的存储方式:结合本地存储和Vuex存储的优势,实现持久化和响应式。

配置Vuex进行Token存储:通过Vuex管理用户状态,并同步到本地存储。

前端路由守卫配置:使用Vue Router的路由守卫保护需要登录才能访问的页面。

登录逻辑与Token处理:在登录成功后保存Token,并在请求头中携带Token。

后端Token验证:使用JWT库验证Token的有效性,确保接口安全。

通过这些步骤,我们可以在Vue.js项目中实现一个安全且用户体验良好的用户登录状态持久化方案。希望本文能为你的项目开发提供有价值的参考。

相关探索