一、当登录按钮被点击时发生了什么?
每个React应用都会遇到这样的核心场景:用户点击登录按钮后,系统如何确认他是否是合法用户?又如何判断他能操作哪些功能?我们通过本地超市的会员系统来理解这个问题:
顾客出示会员卡(凭证验证)→ 收银员检查防伪标记(签名验证)→ 根据会员等级开放权限(角色控制)。这种三层验证机制正是现代Web应用的安全基石。
二、JWT:自包含的电子身份证
2.1 工作原理图解
当用户成功登录后,服务器会生成类似这样的数据结构:
// 技术栈:Node.js + Express
const jwt = require('jsonwebtoken');
// 生成示例令牌
const user = { id: 1001, role: 'editor' };
const token = jwt.sign(
{
user,
// 过期时间(1小时后)
exp: Math.floor(Date.now() / 1000) + 3600
},
'your-256-bit-secret',
{ algorithm: 'HS256' }
);
这段代码会生成类似eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoxMDAx...
的令牌,包含三个组成部分:
- 头部(红色部分):说明使用HS256算法
- 载荷(紫色部分):携带用户信息和过期时间
- 签名(蓝色部分):防篡改验证码
2.2 实战注意事项
// 前端拦截器示例(技术栈:React + Axios)
axios.interceptors.request.use(config => {
const token = localStorage.getItem('jwt');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
// 重要:避免XSS攻击
config.withCredentials = true;
}
return config;
});
黄金法则:
- 始终通过HTTPS传输
- 令牌存储优先选择
httpOnly
的Cookies - 定期刷新令牌(推荐30分钟)
三、OAuth 2.0:第三方授权通行证
3.1 授权码模式流程图解
假设我们要接入GitHub登录:
// 技术栈:React + GitHub OAuth
const redirectToAuth = () => {
const CLIENT_ID = 'your_github_client_id';
const SCOPE = 'user:email,repo';
window.location = `https://github.com/login/oauth/authorize?
client_id=${CLIENT_ID}&scope=${SCOPE}`;
};
// 回调处理
const handleCallback = async () => {
const code = new URLSearchParams(window.location.search).get('code');
const response = await axios.post('/api/oauth/token', { code });
// 获取访问令牌
const { access_token } = response.data;
};
3.2 常见陷阱清单
- 授权码必须通过后端交换令牌(禁止前端直接处理)
- PKCE扩展增强移动端安全性
- 及时撤销不再需要的授权
四、RBAC:指挥中心的权限分配
4.1 权限矩阵设计示例
角色 | 文章查看 | 文章编辑 | 用户管理 |
---|---|---|---|
访客 | √ | × | × |
内容编辑 | √ | √ | × |
系统管理员 | √ | √ | √ |
4.2 动态路由控制实现
// 技术栈:React Router v6
const App = () => (
<Routes>
<Route path="/" element={<PublicPage />} />
<Route element={<AuthLayout />}>
<Route path="dashboard" element={
<RoleRequired allowedRoles={['admin', 'editor']}>
<Dashboard />
</RoleRequired>
}/>
<Route path="admin-panel" element={
<RoleRequired allowedRoles={['admin']}>
<AdminPanel />
</RoleRequired>
}/>
</Route>
</Routes>
);
// 权限高阶组件
const RoleRequired = ({ children, allowedRoles }) => {
const { role } = useAuth();
return allowedRoles.includes(role)
? children
: <Navigate to="/unauthorized" />;
};
五、技术选型指南
5.1 安全方案对照表
特性 | JWT | Session | OAuth |
---|---|---|---|
状态管理 | 无状态 | 有状态 | 混合 |
跨域支持 | ★★★ | ★★ | ★★★ |
第三方集成 | 困难 | 困难 | 容易 |
令牌吊销 | 复杂 | 简单 | 中等 |
5.2 典型组合方案
- 内部系统:JWT + RBAC
- 公众平台:OAuth + ABAC
- 混合架构:JWT前端会话 + OAuth第三方接入
六、安全攻防现场
6.1 常见攻击手段
// CSRF攻击示例
<img src="http://bank.com/transfer?to=hacker&amount=1000000">
// 防御措施:SameSite属性设置
app.use(cookieSession({
keys: ['secret'],
sameSite: 'strict'
}));
6.2 安全头设置清单
add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
七、技术实践路线图
- 开发阶段:使用JWT调试模式(方便问题追踪)
- 测试阶段:自动化扫描令牌泄漏
- 生产环境:开启HSTS强制HTTPS
- 监控预警:异常登录检测系统