概述
last.fm android的认证机制与cookie类似,但与cookie无关。
类似于OAUTH,它也有appKey/appSecret体系,以允许第三方开发者开发应用;然而,这个体系跟OAUTH没有任何关系,last.fm android这个APP也跟第三方开发者没有什么关系。
登录、认证流程
1. 用户输入用户名、密码
2. 客户端把用户名、密码经加密处理后传给服务端,服务端认证通过后,返回一段XML;客户端再把这个XML反序列化为一个JAVA对象:fm.last.api.Session. 这个对象包含userName和一个token(代码中称为sessionKey)
3. 客户端会把对象中的
userName和sessionKey存入到settings中 (SharedPreference)
4. 同时还会把这个Session对象作为一个全局变量放在内存中,相当于setting中所存session信息的缓存
5. 后续的访问中,如果客户端需要表明身份,则会传入sessionKey; 服务端会通过sessionKey来判断该请求是否代表合法的用户。
整个过程类似于服务端返回一个cookie, 客户端在后续请求中发出cookie .
如何记住登录
启动后,在LastFMApplication这个activity的onCreate()中会
去settings中取出已登录的userName和sessionKey ,然后封装出Session对象,作为全局变量放到内存里;接下来直接进入LastFm Activity或Profile Activity,整个过程并没有网络交互。
服务端并没有校验,是不是有安全漏洞? 如果我在首次登录后,把用户名换成另一个人的,就不是可以这个人的身份操作本APP? 答案是:你只能成功进入LastFm和Profile,但无法继续以受害者的身份进行操作;因为在后续的业务数据访问请求中,还是要附带上sessionKey,服务端会根据sessionKey找出你的真实身份。
登出时的行为
登出时会把内存中的Session全局变量置为NULL,并去settings中把userName和sessionKey清除。
这就类似于浏览器中的cookie清除 .
具体使用的通信协议
1.走的是http , 直接用HttpURLConnection; API叫 Parser.getItem(url, params, …)
2.用了https,但不校验任何证书(方法名:trustAllHosts())
附:加密的细节信息
String md5Password = MD5.getInstance().hash(pass); //一次哈希 String authToken = MD5.getInstance().hash(user + md5Password); //再哈希 .... //最后传给服务端的东西 params.put("username", username); params.put("authToken", authToken); params.put("method", "auth.getMobileSession"); //应该是服务端的一个方法 params.put("api_key", api_key); signParams(params); //对所有参数做摘要,其中用到了appSecret作为盐
附:AccountManager在这里有没有起到作用?
last.fm android的认证过程中反复调用了AccountManager的API,但这里AccountManager跟认证没有半毛钱关系。
登录成功后,客户端会把useName保存到settings,同时也会顺便把userName保存到AccountManager中; 登出时,也会去AccountManager里清一下。 然而,在进行远程业务操作时,并不会依赖AccountManager中的任何东西。
那么AccountManager在客户端上到底有什么用?我搜了一下代码,发现它只跟ContentProvider有一点点关系,跟认证没有任何关系。