验证请求头、登陆与认证

前端请求头前端调用后端接口时,通常需要配置请求头(Headers),这些头信息用于身份验证、跨域控制、数据格式定义等。

1.HTTP 请求头的作用HTTP 请求头(Request Headers)是客户端(浏览器、前端应用)发送 HTTP 请求时,附加的键值对信息。

作用包括:

身份认证(Authorization):携带 Token 让后端识别用户身份

数据格式声明(Content-Type / Accept):告诉服务器要发送什么格式的数据、希望返回什么格式的数据

安全性(Referer / Origin):限制请求来源,防止 CSRF 攻击

性能优化(Cache-Control):控制缓存策略,减少不必要的网络请求

跨域请求控制(Access-Control-Allow-Origin):后端允许特定域访问资源

2. 常见的请求头字段

请求头字段

作用

示例值

Authorization

认证 Token

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI...

Content-Type

请求体格式

application/json

Accept

期望的返回格式

application/json

Referer

请求来源

https://example.com

Origin

请求发起者

https://my-frontend.com

User-Agent

客户端信息

Mozilla/5.0 (Windows NT 10.0; Win64; x64)

Cache-Control

缓存策略

no-cache, no-store, must-revalidate

X-Requested-With

标记 AJAX 请求

XMLHttpRequest

APP-DOMAIN

自定义应用标识

my-app-domain

3. 在 Vue 3 中封装全局 Axios(1) 安装 Axiosnpm install axios

(2) 创建 Axios 实例在 src/utils/request.ts(或 request.js或api/index.ts)封装 Axios,设置全局请求头:

import axios from "axios";

import { getToken, refreshToken } from "@/utils/auth"; // 获取 & 刷新 Token

// 创建Axios实例

const service = axios.create({

baseURL: import.meta.env.VITE_API_BASE_URL, // 读取环境变量配置

timeout: 10000, // 设置超时时间10s

headers: {

"Content-Type": "application/json", // 发送 JSON 格式数据

"APP-DOMAIN": "my-app", // 自定义请求头

},

})

// 请求拦截器:在请求发送前自动添加 Token

service.interceptors.request.use(

(config) => {

const token = getToken();

if (token) {

config.headers.Authorization = `Bearer ${token}`;

}

return config;

},

(error) => Promise.reject(error)

);

// 响应拦截器:自动处理错误 & 刷新 Token

service.interceptors.response.use(

async (response) => {

return response.data; // 直接返回后端返回的数据

},

async (error) => {

const { response } = error;

if (response) {

// **处理 401 未授权错误,尝试刷新 Token**

if (response.status === 401) {

const newToken = await refreshToken();

if (newToken) {

error.config.headers.Authorization = `Bearer ${newToken}`;

return service(error.config); // 重新请求

}

}

}

return Promise.reject(error);

}

);

export default service;

4.在 Vue 组件中使用封装的 Axiosimport http from "@/utils/request";

const fetchAuthors = async () => {

try {

const response = await http.post("/v1/site_ugc/author/get", {

phone_number: "",

status: 1,

page: 1,

size: 10,

});

console.log("API 返回的数据:", response);

} catch (error) {

console.error("请求失败:", error);

}

};

fetchAuthors();

5. 如何在 Vue 全局注册 Axios(1) Vue 3 方式在 main.ts 注册 Axios,让所有组件可以直接使用:

import { createApp } from "vue";

import App from "./App.vue";

import http from "@/utils/request";

const app = createApp(App);

app.config.globalProperties.$http = http; // 挂载到 Vue 全局

app.mount("#app");

在组件中直接使用:

this.$http.get("/api/data").then((res) => console.log(res));

(2) Vue 3 + Pinia 全局存储如果你的项目使用 Pinia 管理状态,可以在 store 里全局管理 Axios:

import { defineStore } from "pinia";

import http from "@/utils/request";

export const useApiStore = defineStore("api", {

state: () => ({

http,

}),

});

在组件中:

import { useApiStore } from "@/store/api";

const api = useApiStore();

api.http.get("/api/data").then((res) => console.log(res));

6. 如何查看请求头?(1) Chrome 开发者工具

打开网页,按 F12 或 Ctrl + Shift + I

进入 Network(网络) 选项卡

选择 Fetch/XHR

点击某个请求,在 Headers 里查看 Request Headers

(2) Console 打印在 Axios 请求拦截器里:

service.interceptors.request.use((config) => {

console.log("请求头:", config.headers);

return config;

});

7. 进阶优化(1) 防止重复请求可以使用 axios-cancel 取消重复请求:

import AxiosCancel from "@/utils/axiosCancel";

const axiosCancel = new AxiosCancel();

service.interceptors.request.use((config) => {

axiosCancel.addPending(config);

return config;

});

service.interceptors.response.use(

(response) => {

axiosCancel.removePending(response.config);

return response;

},

(error) => {

axiosCancel.removePending(error.config);

return Promise.reject(error);

}

);

(2) 自动刷新 Token如果 Token 过期,可以使用 refreshToken 自动续签:

import { getToken, refreshToken } from "@/utils/auth";

service.interceptors.response.use(

async (response) => response,

async (error) => {

if (error.response.status === 401) {

const newToken = await refreshToken();

if (newToken) {

error.config.headers.Authorization = `Bearer ${newToken}`;

return service(error.config); // 重新请求

}

}

return Promise.reject(error);

}

);

登录和验证机制1. 登录流程一般前端的登录流程如下:

用户输入 用户名+密码

前端加密(可选)后,发送到后端

后端验证用户信息,返回 Token(JWT)

前端存储 Token(localStorage/sessionStorage/cookie)

之后的请求都在请求头中携带 Token

服务器验证 Token,返回相应数据

流程图:

复制编辑[用户登录] -> [发送账号密码] -> [后端验证] -> [返回 Token]

-> [前端存储 Token] -> [请求时携带 Token] -> [后端验证 Token]

2. Token 认证(JWT)JWT(JSON Web Token)是一种常见的 Token 认证方式,Token 通常包含:

{

"alg": "HS256",

"typ": "JWT"

}

.

{

"user_id": "12345",

"role": "admin",

"exp": 1710000000

}

.

"签名"

其中:

Header(头部):算法信息

Payload(载荷):存储用户 ID、角色、过期时间

Signature(签名):防止篡改

3. Vue 实现登录(1) 创建 API 登录请求在 api/auth.ts 里封装登录接口:

import http from "@/utils/request";

export const login = (data: { username: string; password: string }) => {

return http.post("/api/login", data);

};

(2) Vue 组件实现登录

4. 前端存储 Token常见存储方式:

方式

特点

localStorage

页面刷新后仍存在,但易被 XSS 攻击

sessionStorage

仅在会话期间有效,关闭浏览器后清除

cookie

可设置 HttpOnly 避免 XSS,但请求会自动携带,可能被 CSRF 攻击

封装 Token 读取 & 存储在 utils/auth.ts 里:

const TOKEN_KEY = "access_token";

export const getToken = () => localStorage.getItem(TOKEN_KEY);

export const setToken = (token: string) => localStorage.setItem(TOKEN_KEY, token);

export const removeToken = () => localStorage.removeItem(TOKEN_KEY);

如果是使用cookies

直接使用 document.cookie

const TOKEN_KEY = "access_token";

// 设置 Token(带 HttpOnly 和 Secure 需后端设置)

export const setToken = (token: string, expiresDays = 7) => {

const date = new Date();

date.setTime(date.getTime() + expiresDays * 24 * 60 * 60 * 1000); // 过期时间

document.cookie = `${TOKEN_KEY}=${token}; expires=${date.toUTCString()}; path=/`;

};

// 获取 Token

export const getToken = () => {

const cookies = document.cookie.split("; ");

for (const cookie of cookies) {

const [key, value] = cookie.split("=");

if (key === TOKEN_KEY) return value;

}

return null;

};

// 移除 Token

export const removeToken = () => {

document.cookie = `${TOKEN_KEY}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;

};

使用 js-cookie(推荐)

安装 js-cookie

npm install js-cookie

封装 Token 操作

import Cookies from "js-cookie";

const TOKEN_KEY = "access_token";

// 设置 Token,带过期时间(7 天)

export const setToken = (token: string) => {

Cookies.set(TOKEN_KEY, token, { expires: 7, path: "/" });

};

// 获取 Token

export const getToken = () => Cookies.get(TOKEN_KEY);

// 移除 Token

export const removeToken = () => Cookies.remove(TOKEN_KEY);

localStorage vs. Cookies

存储方式

是否支持 HttpOnly

是否支持跨域

适用场景

localStorage

❌ 不支持

❌ 仅限同源

仅前端可访问,适合存非敏感信息

Cookies

✅ 可设置 HttpOnly

✅ 可跨子域

适用于 Token 存储,安全性更高

如果后端启用了 HttpOnly,则前端无法直接获取 document.cookie,需要改用后端验证 Cookie。

5. 请求拦截器自动携带 Token在 request.ts(封装的 Axios 里),请求时自动添加 Authorization 头:

service.interceptors.request.use(

(config) => {

const token = getToken();

if (token) {

config.headers.Authorization = `Bearer ${token}`;

}

return config;

},

(error) => Promise.reject(error)

);

7. Vue 全局管理用户登录状态(1) 使用 Pinia 管理 Tokenimport { defineStore } from "pinia";

import { getToken, setToken, removeToken } from "@/utils/auth";

export const useAuthStore = defineStore("auth", {

state: () => ({

token: getToken() || "",

}),

actions: {

setToken(token: string) {

this.token = token;

setToken(token);

},

logout() {

this.token = "";

removeToken();

},

},

});

(2) 在组件中使用import { useAuthStore } from "@/store/auth";

const authStore = useAuthStore();

if (!authStore.token) {

console.log("用户未登录");

}

\8. 权限控制

9. 退出登录(1) 清除 Tokenconst handleLogout = () => {

authStore.logout();

router.push("/login");

};