上一篇
安卓单点登录的实现
- 行业动态
- 2025-04-24
- 8
安卓单点登录通过共享Token或OAuth协议实现,用户一次认证后多应用自动登录,常用JWT存储用户态,或集成Firebase/Auth0等服务,跨应用同步身份,简化登录流程并提升安全性
单点登录(SSO)概念
单点登录(Single Sign-On)指用户在多个系统中只需登录一次,后续访问其他系统时无需重复输入账号密码,在安卓应用中,SSO常用于以下场景:
- 同一公司开发的多个App间共享登录状态
- Web端与移动端账号体系互通
- 第三方授权登录(如微信、QQ、Google账号)
实现方案选择
方案类型 | 适用场景 | 代表技术/服务 |
---|---|---|
自建SSO系统 | 企业内部应用、定制化需求高 | OAuth 2.0 + JWT |
第三方SSO服务 | 快速集成、跨平台需求 | Firebase Auth、Auth0 |
社交登录 | 用户基数大、需第三方信任背书 | Google Sign-In、微信开放平台 |
核心技术原理
OAuth 2.0 授权框架
- 客户端(安卓App)请求授权码
- 授权服务器返回临时授权码
- 用授权码换取Access Token
- 通过Token访问资源服务器
Token存储与验证
- 存储方式:SharedPreferences(加密)、SQLite(建议)
- 验证机制:JWT自包含签名,或通过HTTP请求验证
- 有效期:Access Token(15-3600秒)+ Refresh Token(长期)
安卓端实现步骤(以Firebase为例)
集成Firebase SDK
// 项目级build.gradle classpath 'com.google.gms:google-services:4.3.15' // 应用级build.gradle implementation platform('com.google.firebase:firebase-bom:31.5.0') implementation 'com.google.firebase:firebase-auth'
配置Firebase项目
- 在Firebase控制台创建Android应用
- 下载
google-services.json
放入app目录
实现登录逻辑
FirebaseAuth auth = FirebaseAuth.getInstance(); // 邮箱密码登录 auth.signInWithEmailAndPassword(email, password) .addOnCompleteListener(task -> { if (task.isSuccessful()) { // 获取用户信息 FirebaseUser user = auth.getCurrentUser(); } else { // 处理错误 } });
状态保持机制
- 在
onCreate()
中检查登录状态:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); if (user != null) { // 已登录状态处理 } }
- 在
后端配合要点
Token验证接口
- 提供
/verify_token
接口,接收Token并返回用户信息 - 示例响应:
{ "uid": "12345", "iat": 1625478900, "exp": 1625482500, "role": "admin" }
- 提供
会话管理
- 服务器生成JWT时包含
aud
字段(客户端ID) - 移动端存储Token时添加设备标识前缀
- 登出时使Token失效:
DELETE FROM user_sessions WHERE token = ? AND device_id = ?
- 服务器生成JWT时包含
安全加固措施
风险点 | 防护方案 |
---|---|
Token窃取 | HTTPS传输、本地加密存储(AES+Base64) |
有效期滥用 | 设置合理exp 时间、强制刷新机制 |
跨站请求伪造(CSRF) | Token绑定Referer/Origin、使用CAPTCHA二次验证 |
密钥泄露 | 定期轮换签名密钥、HMAC算法+随机盐值 |
常见问题与解决方案
Q1:如何实现多账号同时登录?
- 方案:为每个账号分配独立SQLite记录,用
account_id
区分 - 实现:
CREATE TABLE accounts ( id INTEGER PRIMARY KEY, account_id TEXT UNIQUE, token TEXT, last_login INTEGER );
Q2:如何处理Token过期?
- 方案:监听API错误码,自动触发Refresh流程
- 示例逻辑:
if (response.code == 401) { // 检查Refresh Token是否有效 if (System.currentTimeMillis() < refreshTokenExpireTime) { // 静默刷新Token auth.refreshAuthToken(refreshToken)... } else { // 强制跳转登录页 } }
相关问题与解答
问题1:如何在Web端和移动端共享SSO状态?
解答:
- 采用JWT作为通用凭证,两端使用相同签名密钥
- Web端通过
localStorage
存储Token,移动端使用SQLite - 建立统一验证接口,例如
/api/validate_token
,两端共用 - 注意处理浏览器和App的不同安全域策略,建议使用独立验证域名
问题2:如何防御Token劫持攻击?
解答:
- 设备指纹校验:在Token中嵌入设备ID、IP地址等信息
- 短期有效性:将JWT
exp
设为5-15分钟,减少被盗用风险 - 操作绑定:关键操作(如支付)要求二次验证(短信/生物识别)
- 黑名单机制:发现异常登录后,立即加入Token黑名单列表
- HTTP严格传输安全:强制HSTS策略,防止中间人攻击