一般流程是这样的:
-
用户输入账号密码 → 发请求给后端 → 后端验证成功后返回 token
-
前端拿到 token 后,用
setToken(token)
存入状态 +localStorage
+ 设置 axios 请求头 -
后续页面就能自动带上 token 请求数据了
场景一:用户登录的时候(推荐方式)
你会有一个登录页面,用户填写账号密码后:
import axios from "axios";
import { useAuth } from "./AuthProvider"; // 假设你把 AuthProvider 包好了
const LoginPage = () => {
const { setToken } = useAuth();
const handleLogin = async () => {
const res = await axios.post("/api/login", {
username: "user123",
password: "password123"
});
const token = res.data.token;
setToken(token);
// 这里就触发了 AuthProvider 中的逻辑:设置 axios 请求头 + localStorage
};
return (
<button onClick={handleLogin}>登录</button>
);
};
在这个逻辑中:
-
后端返回 token
-
你用
setToken
存起来(自动进入 localStorage、axios header)
场景二:无感登录(比如用 cookie、或者刷新 token)
假设你后端设计了「用 refreshToken 自动换取新 token」:
你可以在 AuthProvider
组件里做一次尝试请求,比如:
useEffect(() => {
const tryRefreshToken = async () => {
try {
const res = await axios.post("/api/refresh-token");
const newToken = res.data.token;
// 如果情况正常 -> 正常执行
// 如果发现异常 -> 我主动扔个错误
if (newToken) {
setToken(newToken);
} else {
throw new Error("无效 token");
}
} catch (err) {
// 不管是上面我手动扔的,还是系统报的错,都会被抓到这里处理
console.log("自动登录失败,跳转登录页");
setToken(null);
// 你可以在这里跳转登录页
// navigate("/login"); // 如果用了 React Router
}
};
if (!token) {
tryRefreshToken();
}
}, []);
这样用户第一次进入页面时,如果本地没有 token,就尝试刷新获取。
throw new Error(...)
和 catch (err)
的作用和区别
✅ 举个具体例子
const login = async () => {
try {
const res = await axios.post("/api/login", { username, password });
if (!res.data.token) {
throw new Error("后端没有返回 token");
}
setToken(res.data.token);
} catch (err) {
alert("登录失败:" + err.message);
}
};
如果后端返回的是:
{ "message": "用户名或密码错误" }
你这边拿不到 token
,但 HTTP 状态是 200,不会触发 catch,所以你必须自己 throw
错误,这样才能走进 catch
。
无感登录时为什么会有自动登录失败的情况
无感登录的本质
它的目标是:用户打开页面时,不用手动登录,就自动获取有效的 token。
最常见的实现方式是用 refreshToken
,通过一个自动调用 /refresh-token
接口的流程,获取新的 accessToken
,实现“无感知”登录。
❌ 自动登录可能失败的原因
1. refreshToken 已过期或失效
-
每个 token 都有有效期。
-
如果用户很久没访问页面,
refreshToken
已经过期,就不能换新 token 了。 -
后端接口会返回
401
或403
,提示无效。
2. refreshToken 被删除或篡改
-
浏览器的
localStorage
、cookie
被用户清理,或被某些插件修改。 -
本地没有 refreshToken,就不能换取新 token。
3. 用户手动退出过登录
-
如果你实现了退出逻辑,比如点击“退出登录”会清除 refreshToken,那自动登录自然就失效了。
4. 后端设置了强制下线机制
-
比如:一个账号只能在一台设备登录,如果用户在别的设备登录了,之前的 refreshToken 会被废弃。
5. 网络异常
-
用户打开页面时网络不稳定,无法访问
/refresh-token
接口。