当前位置:首页 > VUE

vue实现登录加token

2026-02-22 01:18:32VUE

Vue 实现登录与 Token 管理

登录逻辑实现

在 Vue 项目中实现登录功能通常需要与后端 API 交互。以下是一个基本的登录组件示例:

<template>
  <form @submit.prevent="handleLogin">
    <input v-model="username" placeholder="Username" />
    <input v-model="password" type="password" placeholder="Password" />
    <button type="submit">Login</button>
  </form>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      username: '',
      password: ''
    };
  },
  methods: {
    async handleLogin() {
      try {
        const response = await axios.post('/api/login', {
          username: this.username,
          password: this.password
        });

        const token = response.data.token;
        localStorage.setItem('authToken', token);
        axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
        this.$router.push('/dashboard');
      } catch (error) {
        console.error('Login failed:', error);
      }
    }
  }
};
</script>

Token 存储与管理

登录成功后获得的 token 需要妥善存储和管理:

vue实现登录加token

// 存储 token
localStorage.setItem('authToken', token);

// 设置 axios 默认请求头
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

// 清除 token
localStorage.removeItem('authToken');
delete axios.defaults.headers.common['Authorization'];

路由守卫实现

使用 Vue Router 的路由守卫保护需要认证的路由:

// router.js
import Vue from 'vue';
import Router from 'vue-router';

Vue.use(Router);

const router = new Router({
  routes: [
    { path: '/login', component: Login },
    { 
      path: '/dashboard', 
      component: Dashboard,
      meta: { requiresAuth: true }
    }
  ]
});

router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('authToken');

  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!token) {
      next('/login');
    } else {
      next();
    }
  } else {
    next();
  }
});

export default router;

Axios 拦截器配置

配置请求和响应拦截器处理 token:

vue实现登录加token

// axios 请求拦截器
axios.interceptors.request.use(config => {
  const token = localStorage.getItem('authToken');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
}, error => {
  return Promise.reject(error);
});

// axios 响应拦截器
axios.interceptors.response.use(response => {
  return response;
}, error => {
  if (error.response.status === 401) {
    // token 过期或无效,跳转登录
    localStorage.removeItem('authToken');
    router.push('/login');
  }
  return Promise.reject(error);
});

用户状态管理

对于更复杂的应用,建议使用 Vuex 管理用户状态:

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    token: localStorage.getItem('authToken') || null,
    user: null
  },
  mutations: {
    setToken(state, token) {
      state.token = token;
      localStorage.setItem('authToken', token);
      axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
    },
    clearToken(state) {
      state.token = null;
      localStorage.removeItem('authToken');
      delete axios.defaults.headers.common['Authorization'];
    },
    setUser(state, user) {
      state.user = user;
    }
  },
  actions: {
    async login({ commit }, credentials) {
      const response = await axios.post('/api/login', credentials);
      commit('setToken', response.data.token);
      commit('setUser', response.data.user);
    },
    logout({ commit }) {
      commit('clearToken');
      commit('setUser', null);
    }
  }
});

刷新 Token 处理

处理 token 过期时的自动刷新:

let isRefreshing = false;
let failedQueue = [];

const processQueue = (error, token = null) => {
  failedQueue.forEach(prom => {
    if (error) {
      prom.reject(error);
    } else {
      prom.resolve(token);
    }
  });
  failedQueue = [];
};

axios.interceptors.response.use(response => {
  return response;
}, async error => {
  const originalRequest = error.config;

  if (error.response.status === 401 && !originalRequest._retry) {
    if (isRefreshing) {
      return new Promise((resolve, reject) => {
        failedQueue.push({ resolve, reject });
      }).then(token => {
        originalRequest.headers['Authorization'] = 'Bearer ' + token;
        return axios(originalRequest);
      }).catch(err => {
        return Promise.reject(err);
      });
    }

    originalRequest._retry = true;
    isRefreshing = true;

    try {
      const refreshToken = localStorage.getItem('refreshToken');
      const response = await axios.post('/api/refresh', { refreshToken });
      const newToken = response.data.token;
      store.commit('setToken', newToken);

      processQueue(null, newToken);
      originalRequest.headers['Authorization'] = 'Bearer ' + newToken;
      return axios(originalRequest);
    } catch (err) {
      processQueue(err, null);
      store.dispatch('logout');
      router.push('/login');
      return Promise.reject(err);
    } finally {
      isRefreshing = false;
    }
  }

  return Promise.reject(error);
});

以上实现涵盖了 Vue 项目中登录和 token 管理的主要方面,包括登录组件、token 存储、路由保护、axios 拦截器和状态管理。根据项目需求可以进一步调整和扩展这些实现。

标签: vuetoken
分享给朋友:

相关文章

vue 实现级联

vue 实现级联

Vue 实现级联选择器 级联选择器(Cascader)常用于省市区选择、分类选择等场景。Vue 中可以通过 Element UI、Ant Design Vue 等 UI 库实现,也可以手动封装。…

vue实现上传

vue实现上传

Vue 文件上传实现方法 使用 Vue 实现文件上传可以通过原生 HTML5 的 <input type="file"> 元素结合 Vue 的事件处理和数据绑定来实现。 基础实现步骤…

vue实现getapp

vue实现getapp

Vue 中实现全局获取应用实例的方法 在 Vue 3 中,可以通过 getCurrentInstance 方法获取当前组件实例,但需要明确其使用场景和限制。以下是具体实现方式: 方法一:通过 ge…

vue实现flvvideo

vue实现flvvideo

vue-flv-player 实现 FLV 视频播放 安装依赖包 npm install flv.js vue-flv-player 基础组件引入 <template> <v…

vue轮播实现

vue轮播实现

Vue 轮播实现方法 使用第三方库(推荐) 安装 swiper 或 vue-awesome-swiper 库,快速实现功能丰富的轮播效果。 以 vue-awesome-swiper 为例: npm…

vue实现队列

vue实现队列

Vue 实现队列功能 在 Vue 中实现队列功能可以通过多种方式完成,以下是几种常见的方法: 使用数组模拟队列 队列遵循先进先出(FIFO)原则,可以用数组的 push 和 shift 方法模拟入队…