4. 身份认证与访问控制:多因素认证、OAuth 2.0与JWT、基于角色的访问控制(RBAC)
身份认证和访问控制,说白了就是解决两个问题:“你是谁” 和 “你能干什么”。
我在做电子交易系统安全审计时,发现超过70%的安全漏洞都出在这两个环节。要么是密码太弱被撞库,要么是权限配置不当导致越权操作。嗯,今天咱们就把这块彻底讲透。
4.1 多因素认证:别只靠一个密码
单靠密码认证,就像家里只装一把锁。黑客拿到密码,就等于拿到了你家钥匙。我见过太多因为密码泄露导致账户被盗的案例了。
多因素认证(MFA) 的核心思路是:至少使用两种不同类型的认证因子。
- 知识因素:你知道的东西(密码、PIN码)
- 持有因素:你拥有的东西(手机、硬件令牌)
- 固有因素:你是什么(指纹、人脸)
实战建议:电子交易系统至少启用“密码 + 短信验证码”或“密码 + TOTP”的双因素认证。我个人习惯推荐TOTP(基于时间的一次性密码),因为它不依赖运营商网络,更安全。
我曾经帮一家金融科技公司做安全加固,他们只用了密码认证。结果一次撞库攻击,2000多个账户被盗。后来我们上线了MFA,攻击成功率直接降到了0.1%以下。
避坑指南:我曾经见过一个系统,虽然启用了MFA,但允许用户“记住此设备30天”。这相当于把MFA降级成了单因素认证。记住:MFA的每次登录都应该验证,别为了用户体验牺牲安全。
4.2 OAuth 2.0与JWT:现代认证的基石
OAuth 2.0 是授权框架,JWT 是令牌格式。这两个东西经常一起出现,但很多人搞混了它们的关系。
你想想看,OAuth 2.0 解决的是“我如何授权第三方应用访问我的资源”,而 JWT 解决的是“这个令牌里到底存了什么信息”。
4.2.1 OAuth 2.0 的四种授权模式
| 授权模式 | 适用场景 | 安全级别 |
|---|---|---|
| 授权码模式 | 有后端的Web应用 | 高 |
| 隐式模式 | 纯前端应用(已不推荐) | 低 |
| 密码模式 | 受信任的第一方应用 | 中 |
| 客户端凭证模式 | 服务间通信 | 高 |
我在项目中遇到过,有人把密码模式用在第三方登录上。这其实很危险,因为第三方应用会直接拿到用户的密码。正确的做法是用授权码模式,用户只在认证服务器上输入密码,第三方应用只拿到授权码。
4.2.2 JWT:自包含的令牌
JWT(JSON Web Token)由三部分组成:Header、Payload、Signature。它的好处是自包含,服务器不需要查数据库就能验证用户身份。
// 一个典型的JWT结构
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
重要提醒:JWT的Payload是Base64编码,不是加密!任何人都可以解码看到里面的内容。千万别把密码、信用卡号等敏感信息放在JWT里。我见过有人把用户手机号直接放进去,结果被中间人攻击截获了。
JWT的签名机制保证了令牌的完整性。服务器用密钥验证签名,如果签名不匹配,说明令牌被篡改了。
// 生成JWT的示例(Node.js)
const jwt = require('jsonwebtoken');
const token = jwt.sign(
{ userId: 123, role: 'admin' },
'your-secret-key',
{ expiresIn: '1h' }
);
实战技巧:JWT的过期时间别设太长。我一般设15分钟到1小时。如果需要长期保持登录,用刷新令牌(Refresh Token)来获取新的访问令牌。
4.3 基于角色的访问控制(RBAC)
RBAC 的核心思想是:用户不直接拥有权限,而是通过角色来获得权限。这样管理起来就灵活多了。
举个例子,一个电子交易系统可能有这些角色:
- 普通用户:查看订单、下单、修改个人信息
- 客服:查看所有订单、处理退款
- 管理员:管理用户、配置系统、查看报表
- 超级管理员:所有权限,包括审计日志
我在项目中遇到过,有人把权限直接分配给用户,结果系统里有300多个用户,每个用户的权限都不一样。后来改成RBAC,只定义了5个角色,管理成本直接降了80%。
4.3.1 RBAC的三种模型
| 模型 | 说明 | 适用场景 |
|---|---|---|
| 基本RBAC | 用户-角色-权限 | 小型系统 |
| 层级RBAC | 角色可以继承 | 中型系统 |
| 约束RBAC | 增加职责分离约束 | 金融、政务系统 |
你想想看,在金融系统中,一个用户不能同时拥有“创建订单”和“审核订单”的权限。这就是约束RBAC里的职责分离原则。
4.3.2 RBAC的实现示例
// 权限检查中间件(Node.js)
function checkPermission(requiredRole) {
return (req, res, next) => {
const userRole = req.user.role;
const roleHierarchy = {
'user': 1,
'support': 2,
'admin': 3,
'superadmin': 4
};
if (roleHierarchy[userRole] >= roleHierarchy[requiredRole]) {
next();
} else {
res.status(403).json({ error: '权限不足' });
}
};
}
// 使用示例
app.post('/api/orders', checkPermission('user'), (req, res) => {
// 创建订单逻辑
});
核心原则:最小权限原则。每个角色只分配完成工作所需的最小权限。别图省事给所有人管理员权限,那等于把系统大门敞开了。
4.4 三者如何协同工作
在实际的电子交易系统中,这三者通常是配合使用的:
- 多因素认证:确保登录环节的安全性
- OAuth 2.0 + JWT:管理认证和授权的令牌
- RBAC:控制用户能访问哪些资源
举个例子,用户登录时:
- 输入密码 + 短信验证码(MFA)
- 认证服务器返回JWT(包含用户ID和角色)
- 每次请求携带JWT,后端解析后通过RBAC判断是否有权限
避坑指南:我曾经见过一个系统,JWT里存了角色信息,但后端没有验证角色是否有效。结果攻击者修改JWT里的角色为admin,就能访问所有接口。记住:永远在后端验证权限,别信任前端传来的任何数据。
这张图把整个知识体系串起来了。从MFA的三种认证因素,到OAuth 2.0和JWT的令牌机制,再到RBAC的三种模型,最后三者协同工作。说白了,这就是一套完整的“你是谁 → 你有什么凭证 → 你能干什么”的安全链路。
总结一下:身份认证与访问控制是电子交易系统的第一道防线。MFA解决登录安全,OAuth 2.0 + JWT解决授权和令牌管理,RBAC解决权限控制。三者缺一不可,任何一个环节出问题,整个系统都可能被攻破。