Web 端单点登录(Single Sign On,简称 SSO)很常见,是目前比较流行的企业业务整合的解决方案之一。 SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
如果你不明白移动端单点登录是什么意思,可以看下面这个介绍视频:
那么问题来了,我们该怎么实现呢?
先来看看 Web 端单点登录的实现原理,主要有两种:
- 对于一级域名相同的应用,如a.example.com和b.example.com,我们一般是通过跨域名的共享 Cookie 来实现的,即将 Cookie的域设置为顶域,即.example.com。在 Cookie 中包含了 sessionId,通过此 sessionId 来判断该浏览器是否在其他子业务系统中登录过。
- 对于不同一级域名下的应用,一般通过 CAS 来实现,具体流程相对较为复杂,这里不详细展开了,感兴趣的可以查阅相关文章。
这里我们不妨思考一下方法一的本质,因为这和移动应用单点登录的本质很像。方法一的本质,是想办法共享某种唯一标志,并将此唯一标志和服务器建立起 session,从而实现多个应用登录状态的统一。在 Web 端单点登录这个场景下,唯一标志就是 sessionId,这是由服务器生成的唯一随机字符串,建立 session 就不需要解释了,各种框架都有自己的实现。
那么在移动应用场景下,我们是否可以找到一个唯一标志并将其和服务器建立一个 session 呢?当然可以!比如你可以使用设备 ID (deviceId)作为唯一标志,每次用户在其中一个应用登录之后,都在服务器新建一个 key 为 deviceId 的 session。同一设备上的其他应用登录的时候,获取到的还是同一个 deviceId,这时候我们就有办法知道当前设备是否有已登录账号了。
于是我们的问题就 break down 为了两部分:
- 如何获取设备的唯一标志?
- 如何建立起设备唯一标志和服务器直接的 session 关系?
下面简要介绍一下几个你可能会用到的方法以及需要实现的接口:
- 如何获取设备 ID ?
- 创建一个 session
- 查询 session
- 销毁 session
获取设备 ID
iOS 设备的设备 ID 可以通过identifierForVendor获取,同一个 vendor 的应用获取到的设备 ID 是一样的。如果你的应用不属于同一 vendor,建议使用ASIdentifierManager。
Swift 5 代码示例:
letdeviceId = UIDevice.current.identifierForVendor!.uuidString
Android 设备可通过ANDROID_ID获取:
Java 代码示例:
importandroid.provider.Settings.Secure;
privateString android_id = Secure.getString(
getContext().getContentResolver(), Secure.ANDROID_ID
);
创建一个 session
在移动应用客户端内创建一个 session ,需要移动端用户处于登录状态,一般需要传应用 ID 和设备 ID。你需要在每次用户成功登录时调用此接口。
Swift 代码示例:
这里使用请求头 Authorization 的方式表明当前用户的身份。
func createSession(){
// 移动端 SSO: createSession
struct MobileSSO: Encodable {
letdeviceId:String
letappId:String
}
letbody = MobileSSO(
deviceId: UIDevice.current.identifierForVendor!.uuidString,
appId:"app1"
)
letheaders: HTTPHeaders = [
"Authorization":"JWT TOKEN",
"Accept":"application/json"
]
letapi ="https://yourapp.com/api/sso/createSession"
AF.request(api,method: .post,parameters: body,encoder: JSONParameterEncoder.default,headers: headers).response { responsein
debugPrint(response)
}
}
查询 session
在移动应用客户端内查询 session,不需要用户处于登录态,只需要传入一个 deviceId 即可。你可以在每次用户打开登录注册页时调用此接口,一旦检测到 session,就可以从服务器返回用户信息,从而弹出一个提示框,提示用户是否使用已有账号登录。如下图所示:
销毁 session
在一个移动应用客户端内销毁一个 App session ,用户需处于登录状态。你应该在每次用户退出登录以及删除 App 的时候调用此接口。你可以将你的应用设计为只要某个应用处于登录状态,session 就成立,也可以只要其中一个应用退出登录,session 就失效,这取决于你的具体业务需求。
其他问题
- 如何保证检测 session 时获取用户信息的安全性?
存在第三方非法批量模拟设备 ID 查询 session 的可能。你可以在查询 session 接口只返回昵称和头像,以及用于换取用户信息的 ticket。然后在后端使用 ticket 换取用户信息。在后端可以做各种检测机制,如要求提供应用密钥等。
如果你想快速实现移动应用单点登录,可以实现 Authing 的移动应用 SSO 服务。
相关阅读