前后端分离架构下,Vue 无法直接读取 PHP 的 Session,Session 仅适合后端内部使用,推荐使用Pinia代替。具体实现步骤如下:
1. 后端:在登录成功时返回用户名
你的接口已经返回了 $user 数据,确保 data 中包含 username 字段即可:
dart
// 登录成功,返回用户信息
return json([
'code' => 200,
'msg' => '登录成功',
'data' => [
'username' => $user->username,
'id' => $user->id,
// 其他需要的字段...
]
]);
2. 前端:登录页接收并存入 Pinia
安装 Pinia(如未安装):
npm install pinia
创建用户 Store (src/stores/user.ts):
javascript
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useUserStore = defineStore('user', () => {
const username = ref('')
function setUsername(name: string) {
username.value = name
localStorage.setItem('username', name) // 同时持久化,刷新不丢失
}
function clearUser() {
username.value = ''
localStorage.removeItem('username')
}
return { username, setUsername, clearUser }
})
在登录页调用:
javascript
import { useUserStore } from '@/stores/user'
import { useRouter } from 'vue-router'
const userStore = useUserStore()
const router = useRouter()
async function handleLogin() {
const res = await api.post('/login', { username, password })
if (res.data.code === 200) {
// 将后端返回的用户名存入 Pinia
userStore.setUsername(res.data.data.username)
// 跳转到首页
router.push('/home')
}
}
3. Home 页面:读取用户名展示
xml
<template>
<div>
<p>欢迎回来,{{ userStore.username }}</p>
<button @click="logout">退出登录</button>
</div>
</template>
<script setup lang="ts">
import { useUserStore } from '@/stores/user'
import { useRouter } from 'vue-router'
const userStore = useUserStore()
const router = useRouter()
function logout() {
userStore.clearUser()
router.push('/login')
}
</script>
4. 路由守卫:防止未登录访问 Home
在 src/router/index.ts 中添加全局前置守卫:
vbnet
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('username') // 或用 token 判断
if (to.path === '/home' && !token) {
next('/login')
} else {
next()
}
})
⚠️ 关于 Session 的补充说明
后端代码中的 Session::set('user_name', $username) 依然保留即可,它有以下作用:
- 后端鉴权 :后续接口可通过
Session::get('user_name')判断用户是否登录 - 服务端逻辑:如记录操作日志、权限校验等
但在前后端分离场景下,前端无法直接读取 PHP Session ,所以用户名必须通过 JSON 响应显式返回给前端。如果你需要跨域请求时保持 Session,还需在 axios 中配置 withCredentials: true,并确保后端 CORS 配置允许携带凭证。