Firebase自定义认证:如何正确失效已登录用户并重新认证?
场景说明
我们使用Firebase Custom Auth,通过微服务生成自定义令牌完成iOS客户端登录,相关实现代码如下:
微服务端生成自定义令牌
String uid = "some-uid"; String customToken = FirebaseAuth.getInstance().createCustomToken(uid); // Send token back to client
iOS客户端登录逻辑
// iOS Mobile Client Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in // ... }
当用户账户遭泄露或在微服务端修改密码时,可通过后端调用以下方法吊销用户的刷新令牌:
FirebaseAuth.getInstance().revokeRefreshTokens(uid);
问题
设想的失效并重新认证流程如下:
- 在后端吊销其刷新令牌
- 在后端生成新的自定义令牌并发送给客户端
- 在移动客户端登出用户
- 使用新的自定义令牌重新登录用户
请问该流程是否正确?是否遗漏关键环节?
回答
你的流程方向是对的,但有几处关键细节需要调整和补充,才能确保流程的安全性和有效性:
调整后的完整流程
步骤1:后端吊销刷新令牌并标记用户状态
调用FirebaseAuth.getInstance().revokeRefreshTokens(uid);失效所有现存刷新令牌,但注意:已颁发的ID令牌在默认1小时有效期内仍可正常使用。因此建议同时在后端给该用户标记状态(比如needs_reauth: true),或通过Firebase自定义声明添加该标记,后续验证令牌时需检查此状态。步骤2:触发客户端重新认证(而非主动发送新令牌)
不要提前将新令牌发送给客户端,避免令牌泄露风险。正确做法是:通过FCM推送通知告知客户端"需重新认证",或在客户端发起API请求返回401错误时,触发重新认证流程。步骤3:客户端登出并请求新令牌
客户端收到重新认证指令后,先调用Auth.auth().signOut()完成登出,然后引导用户完成身份验证(比如输入新密码、验证码),验证通过后再向后端请求新的自定义令牌。步骤4:客户端使用新令牌重新登录
客户端获取到新令牌后,调用Auth.auth().signIn(withCustomToken: newCustomToken)完成登录,此时会获得新的有效刷新令牌和ID令牌。
必须补充的关键环节
ID令牌的即时失效处理
由于revokeRefreshTokens无法直接失效已发出的ID令牌,若需立即阻止用户使用旧ID令牌访问资源,需在后端的令牌验证逻辑中,额外检查用户的needs_reauth状态或Firebase自定义声明,拒绝状态异常的令牌请求。新令牌的安全校验
后端生成新自定义令牌前,必须先验证用户的当前身份合法性(比如验证新密码、短信验证码),不能无条件生成令牌,防止恶意利用。客户端异常兜底处理
客户端需在API请求拦截器中处理401错误,自动触发登出和重新认证流程,避免因推送通知未到达导致用户无法正常使用功能。
内容的提问来源于stack exchange,提问作者BlueBoy

