第三方登录-移动端与服务端解决方案

移动端(android)

1.在友盟对各平台封装的基础上再次封装,直接一个回调拿到第三方平台token,openid,unionid,nickname等信息.
这一个方法中包含了用户点击授权拿token,根据token拿个人信息两个步骤.

UmengUtil

//其他平台如loginByWeixin(this, new AuthCallback()
UmengUtil.loginBySina(this, new AuthCallback() {
                    @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:https://api.weibo.com/oauth2/get_token_info
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
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

第三方登录-移动端与服务端解决方案_第1张图片

返回说明
正常情况下,微信会返回下述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网站:https://graph.qq.com/oauth2.0/me
WAP网站:https://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登录或者作为登录验证,过期就用用户名密码登录.

短时频繁登录,以及多台设备抢登的处理

session处理

验证用户名密码或者token通过后,如果同一个user的原session还存在:

先判断是否为同一个ip,如果不是,kill原session,创建新的session.
如果是原ip,就不必创建新的session.

多台设备抢登问题

两台手机相隔很短的事件先后登录同一个账户,如果移动端实现了对用户完全透明的过期重登机制,那么还是会出现看起来两台手机同时登录同一个账户,而对于服务端来说,就是不断地在创建session,销毁session.
怎么处理呢?

服务端的响应多增加一个错误码类别:
原先的:登录token过期一个code
增加的: 其他设备登录的一个code

客户端拿到第二个code时,可以不再做自动重新登录,而是像QQ一样弹出notification通知用户,让用户主动选择.

你可能感兴趣的:(第三方登录-移动端与服务端解决方案)