You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue中如何维持登录用户状态并实现页面权限控制?

嘿,从PHP服务端直接靠会话判断跳转,转到Vue单页应用做登录授权,确实得换个思路——毕竟Vue是前端路由主导的,核心要靠路由守卫配合后端校验来实现。我结合你之前的PHP逻辑,一步步给你拆解怎么搞:

1. 先搞定Vue Router基础配置

首先你得用Vue Router(Vue官方路由工具,没装的话先执行npm install vue-router),先定义路由表,把需要登录的页面和登录页区分开:

// src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue' // 你的需登录页面
import Login from '../views/Login.vue' // 登录页

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    meta: { requiresAuth: true } // 标记该路由需要登录权限
  },
  {
    path: '/login',
    name: 'Login',
    component: Login
  },
  // 其他路由同理,需要登录的就加meta.requiresAuth字段
]

const router = new VueRouter({
  mode: 'history', // 可选,去掉URL里的#号,需要后端配置支持
  routes
})

export default router
2. 全局路由守卫:替代你原来的PHP会话判断

这就对应你之前那段if ($_SESSION['user_id'] > 0)的逻辑——每次路由跳转前,前端先检查登录状态,同时必须和后端校验(避免前端本地存储被篡改):

先写后端的校验接口(比如check-login.php):

<?php
session_start();
header('Content-Type: application/json');

$response = ['loggedIn' => false];
if (isset($_SESSION['user_id']) && $_SESSION['user_id'] > 0) {
  $response['loggedIn'] = true;
  // 可以顺便返回用户信息,比如$response['user'] = ['id' => $_SESSION['user_id'], 'name' => $_SESSION['username']];
}

echo json_encode($response);
?>

然后在Vue的路由守卫里调用这个接口:

// 继续在src/router/index.js里添加
router.beforeEach(async (to, from, next) => {
  // 判断当前路由是否需要登录权限
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
  
  if (requiresAuth) {
    // 需要登录,调用后端接口校验
    try {
      const res = await fetch('/check-login.php')
      const data = await res.json()
      
      if (data.loggedIn) {
        // 已登录,放行
        next()
      } else {
        // 未登录,跳登录页,同时记录当前目标路由,登录后可跳转回来
        next({ name: 'Login', query: { redirect: to.fullPath } })
      }
    } catch (err) {
      // 请求失败,默认跳登录页
      next({ name: 'Login' })
    }
  } else {
    // 不需要登录的路由直接放行
    // 额外处理:如果用户已登录,访问登录页自动跳首页
    if (to.name === 'Login') {
      const res = await fetch('/check-login.php')
      const data = await res.json()
      if (data.loggedIn) {
        next({ name: 'Home' })
      } else {
        next()
      }
    } else {
      next()
    }
  }
})
3. 登录成功后的重定向处理

当用户在登录页提交表单,调用你原来的PHP登录接口(成功后设置SESSION),登录成功后要跳转到用户之前想访问的页面(如果有的话),否则跳首页:

// src/views/Login.vue里的登录方法
async login() {
  try {
    const res = await fetch('/login.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: `username=${this.username}&password=${this.password}`
    })
    const data = await res.json()
    
    if (data.success) {
      // 获取路由里的redirect参数,没有的话默认跳首页
      const redirect = this.$route.query.redirect || '/'
      // 跳转到目标页面
      this.$router.push(redirect)
    } else {
      alert('登录失败:' + data.message)
    }
  } catch (err) {
    alert('登录请求失败')
  }
}
4. 补充:前端状态管理(可选但推荐)

如果你的应用比较复杂,用Vuex管理登录状态会更方便,不用每次都调用后端接口(可以缓存状态,定期校验):

// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    isLoggedIn: false,
    userInfo: null
  },
  mutations: {
    SET_LOGIN_STATE(state, payload) {
      state.isLoggedIn = payload.loggedIn
      state.userInfo = payload.userInfo
    }
  },
  actions: {
    async checkLogin({ commit }) {
      const res = await fetch('/check-login.php')
      const data = await res.json()
      commit('SET_LOGIN_STATE', {
        loggedIn: data.loggedIn,
        userInfo: data.user || null
      })
      return data.loggedIn
    }
  }
})

之后路由守卫里就可以调用Vuex的action:

// 路由守卫里修改
const isLoggedIn = await store.dispatch('checkLogin')
if (isLoggedIn) {
  next()
} else {
  next({ name: 'Login', query: { redirect: to.fullPath } })
}
最后注意点
  • 如果用了history模式,需要在后端(Nginx/Apache)配置重定向,把所有请求指向index.html,否则刷新页面会404
  • 前端本地存储(localStorage)不能完全信任,必须和后端校验登录状态,避免伪造登录
  • 退出登录时,要调用后端接口销毁SESSION,同时清空前端状态

内容的提问来源于stack exchange,提问作者Kalreg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:27:41