美文网首页程序员成长
第三方登录-移动端与服务端解决方案

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

作者: 石野小真人 | 来源:发表于2017-03-16 16:18 被阅读1453次

    移动端(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: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

    返回说明
    正常情况下,微信会返回下述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通知用户,让用户主动选择.

    相关文章

      网友评论

        本文标题:第三方登录-移动端与服务端解决方案

        本文链接:https://www.haomeiwen.com/subject/zbljnttx.html