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 实战建议:三管齐下

说了这么多,落地的时候怎么搞?我总结了一个三步走的方案:

  1. 第一层:密码策略。先堵住最基础的漏洞。用正则校验密码强度,用数据库记录历史密码,用Redis记录登录失败次数。这些代码量不大,但效果立竿见影。
  2. 第二层:MFA。对敏感操作(比如导出客户数据、修改权限、大额订单审批)强制要求MFA。别一上来全量开启,用户会骂娘。先试点,再推广。
  3. 第三层:OAuth2.0集成。如果对接第三方,务必走授权码模式+PKCE。不要用隐式模式(Implicit Grant),那个已经被废弃了。所有令牌走HTTPS传输,别用HTTP。

一句话总结:密码是底线,MFA是防线,OAuth2.0是连接线。三条线都扎紧了,CRM系统的用户认证才算及格。

嗯,今天就聊到这儿。下一章咱们聊聊数据加密——从存储到传输,怎么让数据即使被偷了也读不懂。到时候见。