搜索

📄 文章 📚 合集
热门搜索
🐘 PHP ⚡ Laravel 🎨 Vue.js ⚛️ React 📦 Yii 📘 JavaScript 🗄️ MySQL 🐳 Docker
返回合集

[板块5:静态页面生成器] - 04- 修复API 请求未认证时报错

代码示例
## 问题分析

当前问题:Sanctum Token 过期或无效时,API 返回 401 Unauthenticated,前端没有处理这个状态码,导致页面报错。


## 解决方案

### 修改文件:`resources/js/admin/stores/auth.js`

**修改位置**:在 `checkAuth` 方法和 axios 响应拦截器中添加 401 处理。

**完整代码**:

```javascript
import { defineStore } from 'pinia';
import axios from 'axios';

// 设置 axios 响应拦截器,全局处理 401
axios.interceptors.response.use(
    response => response,
    error => {
        if (error.response && error.response.status === 401) {
            // Token 过期或无效,清除本地存储并跳转到登录页
            localStorage.removeItem('token');
            delete axios.defaults.headers.common['Authorization'];
            // 如果当前不在登录页,则跳转
            if (window.location.pathname !== '/admin/login') {
                window.location.href = '/admin/login';
            }
        }
        return Promise.reject(error);
    }
);

export const useAuthStore = defineStore('auth', {
    state: () => ({
        user: null,
        token: localStorage.getItem('token'),
    }),
    getters: {
        isAuthenticated: (state) => !!state.token,
    },
    actions: {
        async login(email, password) {
            try {
                const response = await axios.post('/api/admin/login', {
                    email,
                    password,
                });
                this.token = response.data.token;
                this.user = response.data.user;
                localStorage.setItem('token', this.token);
                axios.defaults.headers.common['Authorization'] = `Bearer ${this.token}`;
                return true;
            } catch (error) {
                return false;
            }
        },
        async logout() {
            try {
                await axios.post('/api/admin/logout');
            } catch (error) {
                // 忽略退出请求失败,仍然清除本地状态
            }
            this.token = null;
            this.user = null;
            localStorage.removeItem('token');
            delete axios.defaults.headers.common['Authorization'];
        },
        async checkAuth() {
            if (!this.token) return;
            axios.defaults.headers.common['Authorization'] = `Bearer ${this.token}`;
            try {
                const response = await axios.get('/api/admin/user');
                this.user = response.data;
            } catch (error) {
                // 401 会被拦截器处理,这里不需要额外操作
                this.logout();
            }
        },
    },
});
```

**修改原因**:
- 添加 axios 响应拦截器,全局捕获 401 状态码
- 当 token 过期或无效时,自动清除本地存储并跳转到登录页
- 避免用户看到白屏或技术性错误信息

---

🧸 adorable code

专注 PHP、JavaScript、Laravel、Vue.js、React、Yii 全栈开发。记录技术探索过程中的灵感与经验,分享工程实践洞见。

hello@adorablecode.com