您好,登录后才能下订单哦!
在现代Web应用中,用户认证和授权是一个非常重要的部分。通常,我们使用JWT(JSON Web Token)来实现用户认证。然而,JWT有一个缺点:它的有效期是有限的。当JWT过期时,用户需要重新登录,这会影响用户体验。为了解决这个问题,我们可以使用双Token机制来实现无感刷新。
双Token机制是指使用两个Token:Access Token和Refresh Token。Access Token用于访问受保护的资源,而Refresh Token用于在Access Token过期时获取新的Access Token。通过这种方式,我们可以在用户不知情的情况下刷新Access Token,从而实现无感刷新。
首先,我们需要安装一些必要的依赖:
npm install axios vue-router pinia
axios
:用于发送HTTP请求。vue-router
:用于路由管理。pinia
:用于状态管理。我们需要创建一个Axios实例,并配置请求拦截器和响应拦截器。
// src/utils/axios.js
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
});
// 请求拦截器
instance.interceptors.request.use(
(config) => {
const accessToken = localStorage.getItem('accessToken');
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
const refreshToken = localStorage.getItem('refreshToken');
if (refreshToken) {
try {
const response = await axios.post('/auth/refresh', { refreshToken });
const { accessToken } = response.data;
localStorage.setItem('accessToken', accessToken);
originalRequest.headers.Authorization = `Bearer ${accessToken}`;
return instance(originalRequest);
} catch (err) {
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
window.location.href = '/login';
}
}
}
return Promise.reject(error);
}
);
export default instance;
我们需要配置路由,以便在用户未登录时重定向到登录页面。
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import Login from '../views/Login.vue';
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { requiresAuth: true },
},
{
path: '/login',
name: 'Login',
component: Login,
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
router.beforeEach((to, from, next) => {
const accessToken = localStorage.getItem('accessToken');
if (to.meta.requiresAuth && !accessToken) {
next('/login');
} else {
next();
}
});
export default router;
我们需要创建一个Pinia Store来管理用户状态。
// src/store/auth.js
import { defineStore } from 'pinia';
import axios from '../utils/axios';
export const useAuthStore = defineStore('auth', {
state: () => ({
user: null,
}),
actions: {
async login(credentials) {
const response = await axios.post('/auth/login', credentials);
const { accessToken, refreshToken } = response.data;
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', refreshToken);
this.user = response.data.user;
},
async logout() {
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
this.user = null;
},
},
});
最后,我们可以在组件中使用Pinia Store来处理用户登录和注销。
<!-- src/views/Login.vue -->
<template>
<div>
<form @submit.prevent="login">
<input v-model="email" type="email" placeholder="Email" />
<input v-model="password" type="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
</div>
</template>
<script>
import { useAuthStore } from '../store/auth';
export default {
data() {
return {
email: '',
password: '',
};
},
methods: {
async login() {
const authStore = useAuthStore();
await authStore.login({
email: this.email,
password: this.password,
});
this.$router.push('/');
},
},
};
</script>
<!-- src/views/Home.vue -->
<template>
<div>
<h1>Welcome, {{ user.name }}</h1>
<button @click="logout">Logout</button>
</div>
</template>
<script>
import { useAuthStore } from '../store/auth';
export default {
computed: {
user() {
const authStore = useAuthStore();
return authStore.user;
},
},
methods: {
async logout() {
const authStore = useAuthStore();
await authStore.logout();
this.$router.push('/login');
},
},
};
</script>
通过使用双Token机制,我们可以在用户不知情的情况下刷新Access Token,从而实现无感刷新。这种方法不仅提高了用户体验,还增强了应用的安全性。希望这篇文章能帮助你理解如何在Vue3和Vite中使用双Token实现无感刷新。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。