第三方登入 - 移動端與服務端解決方案

水牛發表於2017-03-16

移動端(android)

1.在友盟對各平臺封裝的基礎上再次封裝,直接一個回撥拿到第三方平臺token,openid,unionid,nickname等資訊.
這一個方法中包含了使用者點選授權拿token,根據token拿個人資訊兩個步驟.

庫地址參見:UmengUtil

//其他平臺如loginByWeixin(this, new AuthCallback<WeixinInfo>()
UmengUtil.loginBySina(this, new AuthCallback<SinaInfo>() {
                    @Override
                    public void onComplete(int var2, SinaInfo info) {
                        Log.e("dd",info.toString());

                    }

                    @Override
                    public void onError( int var2, Throwable var3) {

                    }

                    @Override
                    public void onCancel( int var2) {

                    }
                });複製程式碼

2.然後,把必要的資訊傳送到服務端

服務端

拿到token,openid等關鍵資訊,呼叫各平臺的api進行資訊核對校驗,
如果通過,執行下一步:
根據第三方的openid/unionid去我們的資料庫查閱,
如果沒有賬戶,則生成新的賬戶.如果有賬戶,就不用生成.
最後,將賬戶個人資訊取出,返回給客戶端.
這樣,就完成了登入操作.

資訊校驗的api:

校驗的規則一般都是: 根據客戶端傳來的token去各平臺拿openid,然後與客戶端傳來的openid比對,如果一致,就代表客戶端資料沒問題,校驗無誤.

sina

OAuth2/get_token_info
查詢使用者access_token的授權相關資訊,包括授權時間,過期時間和scope許可權。

URL:api.weibo.com/oauth2/get_…
HTTP請求方式:POST
請求引數
access_token:使用者授權時生成的access_token。
返回資料
{ "uid": 1073880650, "appkey": 1352222456, "scope": null, "create_at": 1352267591, "expire_in": 157679471 }

微信

獲取使用者基本資訊(包括UnionID機制)

注: 在微信賬戶體系中,unionid才是一個微信賬戶的唯一標識(而openid是跟公眾號,服務號等發生關聯產生的),所以微信的校驗是通過token和openid來獲取unionid,然後與客戶端傳來的unionid進行比對校驗.

http請求方式: GET
api.weixin.qq.com/cgi-bin/use…

第三方登入 - 移動端與服務端解決方案

返回說明
正常情況下,微信會返回下述JSON資料包給公眾號:

{ "subscribe": 1, 
"openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", 
"nickname": "Band",
 "sex": 1, 
"language": "zh_CN",
 "city": "廣州", 
"province": "廣東", 
"country": "中國",
 "headimgurl": "[http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0](http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0)", 
"subscribe_time": 1382694957, 
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL",
 "remark": "",
 "groupid": 0}複製程式碼

QQ

獲取使用者OpenID_OAuth2.0

1 請求地址
PC網站:graph.qq.com/oauth2.0/me
WAP網站:graph.z.qq.com/moc2/me
2 請求方法:GET
3 請求引數:access_token
4 返回說明
PC網站接入時,獲取到使用者OpenID,返回包如下:
callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} );

注意解析openid時要將外層括號去掉才能拿到json.

永久登入的實現

問題

看起來像掉線

第三方授權和獲取資訊時,友盟工具會將相關資訊在本地儲存一份,以實現下次不用再吊起授權介面讓使用者再次點選.
但是,第三方token都是有過期時間的.超過了這個時間,授權介面是會被吊起的,這給使用者看起來就好像莫名其妙掉線了,體驗非常不好,那麼,要怎麼實現移動端第三方登入的永久登入呢?

一個解決方式

將第三方登入轉變成賬號密碼登入:

在這臺手機上第一次用第三方登入時,當然是吊起授權介面.
當服務端判定登入成功時,返回第三方賬戶體系的使用者id(openid/unionid)或者內部賬戶體系的uid,和服務端生成的一個密碼(UUID等演算法ramdom出來,反正不用使用者記)
客戶端拿到這兩個資料,加密後儲存到本地,下次進入app時,直接用這兩個來登入.

更進一步

token

為了避免每次都傳輸使用者名稱密碼(即使加了密,在網路暴露太多也不好),可以在登入成功後,服務端生成一個token和規定其有效期(設定長一點,十幾天一個月之類的),並下發,
每次客戶端拿本地token,判斷有效期,在有效期內用token登入或者作為登入驗證,過期就用使用者名稱密碼登入.

短時頻繁登入,以及多臺裝置搶登的處理

session處理

驗證使用者名稱密碼或者token通過後,如果同一個user的原session還存在:

先判斷是否為同一個ip,如果不是,kill原session,建立新的session.
如果是原ip,就不必建立新的session.

多臺裝置搶登問題

兩臺手機相隔很短的事件先後登入同一個賬戶,如果移動端實現了對使用者完全透明的過期重登機制,那麼還是會出現看起來兩臺手機同時登入同一個賬戶,而對於服務端來說,就是不斷地在建立session,銷燬session.
怎麼處理呢?

服務端的響應多增加一個錯誤碼類別:
原先的:登入token過期一個code
增加的: 其他裝置登入的一個code

客戶端拿到第二個code時,可以不再做自動重新登入,而是像QQ一樣彈出notification通知使用者,讓使用者主動選擇.

相關文章