egretios包接微信/facebook登陆

ios包有了,如今须要登陆,就先使用微信登陆吧,后继加一个facebook登陆。html

根据个人理解,先预测一下应该是怎么回事吧。ios

首先应该是要去微信的公共平台注册一下,说个人应用是什么应用,要填写企业信息之类的,还要传什么资质这些。这样以后咱们就能够获得一个code1,用来惟一标识个人这个应用。api

 

有了code1以后,咱们就能够搞开发了。在代码里面调用微信的api接口,同时须要将code1传入。应该还须要其余什么参数,具体的到微信sdk官网去查吧。这时候就会拉起微信登陆了。微信登陆成功以后/或者已经登陆了的,微信那边会弹出界面(是否容许登陆xxx应用,而且使用你的xxx信息),这样以后玩家就能够点击容许/拒绝,容许以后微信就将玩家的信息返回到我刚才调用的sdk哪里。 这样游戏就得到了玩家的帐号信息了。bash

玩家得到帐号信息以后,就拿着帐号信息去服务端登陆,从而进入游戏,开始放肆的玩游戏了。服务器

 

以上只是想了一个大概的逻辑,看着挺简单的,实际操做起来不知道要多长时间才能完成,毕竟我仍是一个懒王。。。。微信

 

 

思路已经有了,如今就开始。。。吧app

 

 

以上都是个人自觉得是的意淫。ide

直到我看到了这篇博客:https://www.cnblogs.com/benwu/articles/5705604.html网站

准备工做

在微信开放平台 https://open.weixin.qq.com/ 注册成为开发者,具体步骤略ui

微信登陆接入

微信登陆遵循协议Aouth2.0中的受权码模式

咱们来看一下Aouth2.0中的受权码模式是怎么定义的:

受权码模式(authorization code)是功能最完整、流程最严密的受权模式。它的特色就是经过客户端的后台服务器,与”服务提供商”的认证服务器进行互动。 
它的步骤以下:

(A)用户访问客户端,后者将前者导向认证服务器。

(B)用户选择是否给予客户端受权。

(C)假设用户给予受权,认证服务器将用户导向客户端事先指定的”重定向URI”(redirection URI),同时附上一个受权码。

(D)客户端收到受权码,附上早先的”重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。

(E)认证服务器核对了受权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)

微信登陆的官方文档将微信登陆分为3个步骤:

第一步.请求code

{
    // send oauth request Final SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "wechat_sdk_demo_test"; api.sendReq(req); } 

 

用这段代码向微信开放平台请求受权码code,可拉起微信并打开受权登陆页(前提是你安装了微信应用并已登陆,未登陆的会引导你先登陆),以下图:

1.若是微信受权页不显示,请检查你的APP签名是否和你在腾讯开放平台的APP签名一致,不一致可修改腾讯开放平台中的APP签名,修改后重装微信或清除微信数据后重试。

2.在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity(例如应用程序的包名为net.sourceforge,则新的包名为:net.sourceforge.wxapi),此处应注意包名不要弄错,新增类的名字必须为WXEntryActivity。

返回说明 
用户点击受权后,微信客户端会被拉起,跳转至受权界面,用户在该界面点击容许或取消,SDK经过SendAuth的Resp返回数据给调用方。回调WXEntryActivity中的onResp(BaseResp resp)方法,以下:

复制代码
    @Override
    public void onResp(BaseResp resp) {
        int errorCode = resp.errCode;
        switch (errorCode) {
        case BaseResp.ErrCode.ERR_OK:
            //用户赞成
            String code = ((SendAuth.Resp) resp).code;
            break;
        case BaseResp.ErrCode.ERR_AUTH_DENIED:
            //用户拒绝
            break;
        case BaseResp.ErrCode.ERR_USER_CANCEL:
            //用户取消
            break;
        default:
            break;
        }
        ToastUtil.showMessageLong(this, resp.errStr);
    }
复制代码

客户端收到受权码后,向本身的服务器发起登陆请求,并附带收到的受权码。

服务端收到登陆请求,向微信开放平台请求获取access_token,微信开放平台返回Json字符串:

第二步:经过code获取access_token(在本身服务器端作)

获取第一步的code后,请求如下连接获取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

复制代码
   private String getAccessToken(String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        URI uri = URI.create(url);
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(uri);

        HttpResponse response;
        try {
            response = client.execute(get);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();

                BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
                StringBuilder sb = new StringBuilder();

                for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                    sb.append(temp);
                }

                JSONObject object = new JSONObject(sb.toString().trim());
                accessToken = object.getString("access_token");
                openID = object.getString("openid");
                refreshToken = object.getString("refresh_token");
                expires_in = object.getLong("expires_in");
                return accessToken;
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block 
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }
复制代码

 

参数说明

参数        是否必须        说明 
appid       是          应用惟一标识,在微信开放平台提交应用审核经过后得到

secret      是          应用密钥AppSecret,在微信开放平台提交应用审核经过后得到

code        是         填写第一步获取的code参数

grant_type  是        填authorization_code回说明**

正确的返回:

复制代码
{ 
    "access_token":"ACCESS_TOKEN", 
    "expires_in":7200, 
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID", 
    "scope":"SCOPE",
    "unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
复制代码
参数                              说明
access_token                    接口调用凭证
expires_in  access_token        接口调用凭证超时时间,单位(秒)
refresh_token                   用户刷新access_token
openid                          受权用户惟一标识
scope                           用户受权的做用域,使用逗号(,)分隔
unionid                  只有在用户将公众号绑定到微信开放平台账号后,才会出现该字段。
服务端收到返回的access_token,将access_token,expires_in,access_token是否有效 等数据返回给客户端,客户端成功登陆错误返回样例:
{"errcode":40029,"errmsg":"invalid code"}

   客户端可利用已有的access_token获取微信用户信息

第三步:经过access_token调用接口

获取access_token后,进行接口调用,有如下前提:

  1. access_token有效且未超时;
  2. 微信用户已受权给第三方应用账号相应接口做用域(scope)。

对于接口做用域(scope),能调用的接口有如下:

受权做用域(scope)             接口                接口说明
snsapi_base          /sns/oauth2/access_token 经过code换取 access_token、refresh_token和已受权scope /sns/oauth2/refresh_token 刷新或续期access_token使用 /sns/auth 检查access_token有效性 snsapi_userinfo /sns/userinfo   获取用户我的信息 

其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可让移动端网页受权绕过跳转受权登陆页请求用户受权的动做,直接跳转第三方网页带上受权临时票据(code),但会使得用户已受权做用域(scope)仅为snsapi_base,从而致使没法获取到须要用户受权才容许得到的数据和基础功能。

以获取用户信息为例:

复制代码
private void getUserInfo() {
    if (isAccessTokenIsInvalid() && System.currentTimeMillis() < expires_in) {
        String uri = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openID;
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(URI.create(uri));
        try {
        HttpResponse response = client.execute(get);
        if (response.getStatusLine().getStatusCode() == 200) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
            StringBuilder builder = new StringBuilder();
            for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
            builder.append(temp);
            }
            JSONObject object = new JSONObject(builder.toString().trim());
            String nikeName = object.getString("nickname");
        }
        } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
    }
}
复制代码

 

微信重复登陆

假设用户已经得到受权,则下次登陆时只须要验证access_token是否有效,无效则从新获取受权,有效则无需从新得到受权。

1.用户向本身的服务器请求登陆,登陆方式为微信登陆,附带上次登陆返回的的access_token

2.服务器收到用户的登陆请求,向微信开放平台发送access_token是否有效的验证请求以下

复制代码
private boolean isAccessTokenIsInvalid() {
        String url = "https://api.weixin.qq.com/sns/auth?access_token=" + accessToken + "&openid=" + openID;
        URI uri = URI.create(url);
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(uri);
        HttpResponse response;
        try {
            response = client.execute(get);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();

                BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
                StringBuilder sb = new StringBuilder();

                for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                    sb.append(temp);
                }
                JSONObject object = new JSONObject(sb.toString().trim());
                int errorCode = object.getInt("errcode");
                if (errorCode == 0) {
                    return true;
                }
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;
    }
复制代码
返回说明
正确的Json返回结果:
{ 
 "errcode":0,"errmsg":"ok" } 错误的Json返回示例: {  "errcode":40003,"errmsg":"invalid openid" }

 若是access_token有效,服务端将信息返回给客户端,客户端成功登陆。

若是access_token无效,服务端向微信开放平台发送刷新access_token的请求以下:

access_token是调用受权关系接口的调用凭证,因为access_token有效期(目前为2个小时)较短,当access_token超时后,可使用refresh_token进行刷新,access_token刷新结果有两种:

1.若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间; 
2.若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,至关于续期access_token。

refresh_token拥有较长的有效期(30天),当refresh_token失效的后,须要用户从新受权。

复制代码
private void refreshAccessToken() {
        String uri = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + APP_ID + "&grant_type=refresh_token&refresh_token=" + refreshToken;
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(URI.create(uri));
        try {
            HttpResponse response = client.execute(get);
            if (response.getStatusLine().getStatusCode() == 200) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
                StringBuilder builder = new StringBuilder();
                for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                    builder.append(temp);
                }
                JSONObject object = new JSONObject(builder.toString().trim());
                accessToken = object.getString("access_token");
                refreshToken = object.getString("refresh_token");
                openID = object.getString("openid");
                expires_in = object.getLong("expires_in");
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}
复制代码

返回说明
正确的返回:
复制代码
{ 
    "access_token":"ACCESS_TOKEN", 
    "expires_in":7200, 
    "refresh_token":"REFRESH_TOKEN", 
    "openid":"OPENID", 
    "scope":"SCOPE" 
}
复制代码
参数 说明 access_token 接口调用凭证 expires_in access_token接口调用凭证超时时间,单位(秒) refresh_token 用户刷新access_token openid 受权用户惟一标识 scope 用户受权的做用域,使用逗号(,)分隔 错误返回样例: { "errcode":40030,"errmsg":"invalid refresh_token" }

3.服务端获取到新的access_token等信息,并返回给客户端,客户端成功登陆或者从新获取受权。

 

 

我才知道有一个叫作OAuth的标准。OAuth标准容许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

容许用户提供一个令牌而不是用户名和密码来访问他们存放在特定服务提供者的数据。每个令牌受权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth容许用户受权第三方网站访问他们存储在另外的服务提供者上的信息,而不须要分享他们的访问许可或他们数据的全部内容。

这个标准真是一个好东西。

 

微信就是遵循OAuth2.0开放受权标准的。

 

 

Aouth2.0中的受权码模式定义:

受权码模式(authorization code)是功能最完整、流程最严密的受权模式。它的特色就是经过客户端的后台服务器,与”服务提供商”的认证服务器进行互动。 

 

具体步骤以下:

1.玩家访问客户端->点击微信登陆->微信检查app的签名和在开放平台登记的签名是否一致,若是一致,拉起受权界面->玩家赞成->返回受权码给游戏->游戏使用受权码向游戏服务器->游戏服务器根据受权码去微信服务器请求token->若是微信服务器判断这个受权码有效->返回这个用户正确的token->服务器告诉客户端登陆成功->客户端能够利用token获取微信信息

相关文章
相关标签/搜索