4、用户认证安全:密码策略、多因素认证(MFA)、OAuth2.0集成
用户认证,说白了就是「你怎么证明你是你」。在CRM系统里,这层要是没守住,后面所有数据加密都是白搭。我见过太多项目,花大价钱买了防火墙、做了数据脱敏,结果一个弱口令就让整个系统裸奔了。
今天咱们就聊聊认证安全的三个核心环节:密码策略怎么定、多因素认证怎么落地、OAuth2.0怎么安全集成。嗯,都是我在实际项目中踩过坑、填过土的东西。
4.1 密码策略:别让用户自己坑自己
你想想看,用户为了好记,密码设成「123456」或者「password2024」,这跟把钥匙挂在门上有什么区别?我建议密码策略至少要覆盖这几个维度:
- 复杂度要求:至少8位,包含大小写字母、数字、特殊字符。别搞太复杂,12位以上带符号那种,用户记不住就会贴便签在显示器上——我亲眼见过。
- 历史密码禁止复用:至少记住最近5次。很多系统只禁止当前密码,用户改一次又改回来,等于没改。
- 定期轮换:90天强制更换一次。但别太频繁,30天换一次用户会疯,反而容易写出规律性密码。
- 登录失败锁定:连续5次失败,锁定账号15分钟。这个能有效防止暴力破解。
核心原则:密码策略不是越严越好,要在安全性和用户体验之间找平衡。太严了用户会想办法绕过,反而更危险。
我在项目中遇到过一件事:某销售总监嫌密码太复杂,直接让IT把密码改成「Abc@1234」,然后全部门共用。后来系统被撞库攻击,整个客户数据被拖走。嗯,从那以后我坚持一个原则——密码策略必须配合用户教育,光靠技术手段不够。
4.2 多因素认证(MFA):加一把锁更安心
密码再强,也怕泄露。多因素认证就是再加一道保险。说白了,就是「你知道的 + 你拥有的 + 你本身的」至少组合两种。
常见的MFA方式有这些:
| 因素类型 | 常见实现 | 安全等级 | 用户体验 |
|---|---|---|---|
| 你知道的 | 密码、PIN码 | 低 | 高 |
| 你拥有的 | 手机验证码、硬件Token、TOTP | 中 | 中 |
| 你本身的 | 指纹、人脸、声纹 | 高 | 高 |
我个人习惯在CRM系统中这样配置MFA:
- 内部员工:密码 + TOTP(基于时间的一次性密码)。推荐用Google Authenticator或Microsoft Authenticator,免费且安全。
- 外部合作伙伴:密码 + 短信验证码。虽然短信有被拦截的风险,但胜在门槛低,对方不需要装额外App。
- 管理员账号:密码 + 硬件U2F密钥。这个级别必须上硬件,我见过管理员账号被钓鱼的案例,太惨了。
避坑指南:我曾经在项目中直接上了生物识别,结果发现部分老员工的手机不支持指纹,导致无法登录。后来我学乖了——MFA一定要提供至少两种备选方案,比如TOTP不行就发邮件验证码。
4.3 OAuth2.0集成:别把令牌当通行证
现在很多CRM系统需要对接第三方——比如用微信登录、对接钉钉、或者集成Salesforce。OAuth2.0是行业标准协议,但实现起来坑不少。
先看一个标准的授权码流程:
// 1. 用户点击「微信登录」,前端跳转到微信授权页
GET https://open.weixin.qq.com/connect/oauth2/authorize?
response_type=code&
client_id=YOUR_APP_ID&
redirect_uri=https://crm.example.com/callback&
scope=snsapi_userinfo&
state=随机防伪造字符串
// 2. 用户授权后,微信回调到redirect_uri,带上code
// 3. 后端用code换取access_token
POST https://api.weixin.qq.com/sns/oauth2/access_token
appid=YOUR_APP_ID
secret=YOUR_APP_SECRET
code=收到的code
grant_type=authorization_code
// 4. 用access_token获取用户信息
GET https://api.weixin.qq.com/sns/userinfo?
access_token=返回的token&
openid=用户的openid
这里有几个关键点,我建议你特别注意:
- state参数必须用:防止CSRF攻击。我见过有人偷懒不传state,结果被攻击者伪造回调地址,直接拿到用户授权。
- code只能使用一次:拿到access_token后,code立即失效。这是OAuth2.0的基本安全设计。
- access_token不要暴露在前端:所有令牌交换必须在后端完成。前端只负责跳转和接收code。
- refresh_token要妥善保管:它相当于长期有效的通行证,泄露了等于账号被盗。建议加密存储,且设置较短的有效期。
警告:千万不要把client_secret硬编码在移动端或前端代码里。我曾经审计过一个项目,他们把secret写在iOS的plist文件里,反编译就能看到。正确的做法是:移动端使用PKCE(Proof Key for Code Exchange)流程,不需要secret。
为什么会这样?因为OAuth2.0本质上是一个授权协议,不是认证协议。它只告诉系统「这个用户授权了哪些权限」,但不保证「这个用户就是本人」。所以,我建议在OAuth2.0之上再加一层ID Token(OpenID Connect),才能真正确认用户身份。
4.4 实战建议:三管齐下
说了这么多,落地的时候怎么搞?我总结了一个三步走的方案:
- 第一层:密码策略。先堵住最基础的漏洞。用正则校验密码强度,用数据库记录历史密码,用Redis记录登录失败次数。这些代码量不大,但效果立竿见影。
- 第二层:MFA。对敏感操作(比如导出客户数据、修改权限、大额订单审批)强制要求MFA。别一上来全量开启,用户会骂娘。先试点,再推广。
- 第三层:OAuth2.0集成。如果对接第三方,务必走授权码模式+PKCE。不要用隐式模式(Implicit Grant),那个已经被废弃了。所有令牌走HTTPS传输,别用HTTP。
一句话总结:密码是底线,MFA是防线,OAuth2.0是连接线。三条线都扎紧了,CRM系统的用户认证才算及格。
嗯,今天就聊到这儿。下一章咱们聊聊数据加密——从存储到传输,怎么让数据即使被偷了也读不懂。到时候见。