微信登录接入

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

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

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

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

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

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

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

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

第一步.请求code

1
2
3
4
5
6
7
{
    // 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)方法,如下:

 1 @Override2     public void onResp(BaseResp resp) {3         int errorCode = resp.errCode;4         switch (errorCode) {5         case BaseResp.ErrCode.ERR_OK:6             //用户同意7             String code = ((SendAuth.Resp) resp).code;8             break;9         case BaseResp.ErrCode.ERR_AUTH_DENIED:
10             //用户拒绝
11             break;
12         case BaseResp.ErrCode.ERR_USER_CANCEL:
13             //用户取消
14             break;
15         default:
16             break;
17         }
18         ToastUtil.showMessageLong(this, resp.errStr);
19     }

客户端收到授权码后,向自己的服务器发起登录请求,并附带收到的授权码。

服务端收到登录请求,向微信开放平台请求获取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

 1 private String getAccessToken(String code) {2         String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";3         URI uri = URI.create(url);4         HttpClient client = new DefaultHttpClient();5         HttpGet get = new HttpGet(uri);6 7         HttpResponse response;8         try {9             response = client.execute(get);
10             if (response.getStatusLine().getStatusCode() == 200) {
11                 HttpEntity entity = response.getEntity();
12
13                 BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
14                 StringBuilder sb = new StringBuilder();
15
16                 for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
17                     sb.append(temp);
18                 }
19
20                 JSONObject object = new JSONObject(sb.toString().trim());
21                 accessToken = object.getString("access_token");
22                 openID = object.getString("openid");
23                 refreshToken = object.getString("refresh_token");
24                 expires_in = object.getLong("expires_in");
25                 return accessToken;
26             }
27         } catch (ClientProtocolException e) {
28             // TODO Auto-generated catch block
29             e.printStackTrace();
30         } catch (IOException e) {
31             // TODO Auto-generated catch block
32             e.printStackTrace();
33         } catch (IllegalStateException e) {
34             // TODO Auto-generated catch block
35             e.printStackTrace();
36         } catch (JSONException e) {
37             // TODO Auto-generated catch block
38             e.printStackTrace();
39         }
40
41         return null;
42     }

参数说明

参数        是否必须        说明
appid       是        应用唯一标识,在微信开放平台提交应用审核通过后获得secret      是        应用密钥AppSecret,在微信开放平台提交应用审核通过后获得code        是        填写第一步获取的code参数grant_type  是        填authorization_code回说明**

正确的返回:

1 {
2 "access_token":"ACCESS_TOKEN",
3 "expires_in":7200,
4 "refresh_token":"REFRESH_TOKEN",
5 "openid":"OPENID",
6 "scope":"SCOPE",
7 "unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
8 }

 参数                              说明
access_token                    接口调用凭证
expires_in  access_token        接口调用凭证超时时间,单位(秒)
refresh_token                   用户刷新access_token
openid                          授权用户唯一标识
scope                           用户授权的作用域,使用逗号(,)分隔
unionid                         只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。

服务端收到返回的access_token,将access_token,expires_in,access_token是否有效 等数据返回给客户端,客户端成功登录

客户端可利用已有的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,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。

以获取用户信息为例:
 1 private void getUserInfo() {2         if (isAccessTokenIsInvalid() && System.currentTimeMillis() < expires_in) {3             String uri = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openID;4             HttpClient client = new DefaultHttpClient();5             HttpGet get = new HttpGet(URI.create(uri));6             try {7                 HttpResponse response = client.execute(get);8                 if (response.getStatusLine().getStatusCode() == 200) {9                     BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
10                     StringBuilder builder = new StringBuilder();
11                     for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
12                         builder.append(temp);
13                     }
14                     JSONObject object = new JSONObject(builder.toString().trim());
15                     String nikeName = object.getString("nickname");
16                 }
17             } catch (ClientProtocolException e) {
18                 // TODO Auto-generated catch block
19                 e.printStackTrace();
20             } catch (IOException e) {
21                 // TODO Auto-generated catch block
22                 e.printStackTrace();
23             } catch (JSONException e) {
24                 // TODO Auto-generated catch block
25                 e.printStackTrace();
26             }
27         }
28     }

微信重复登录

假设用户已经获得授权,则下次登录时只需要验证access_token是否有效,无效则重新获取授权,有效则无需重新获得授权。

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

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

 1 private boolean isAccessTokenIsInvalid() {2         String url = "https://api.weixin.qq.com/sns/auth?access_token=" + accessToken + "&openid=" + openID;3         URI uri = URI.create(url);4         HttpClient client = new DefaultHttpClient();5         HttpGet get = new HttpGet(uri);6         HttpResponse response;7         try {8             response = client.execute(get);9             if (response.getStatusLine().getStatusCode() == 200) {
10                 HttpEntity entity = response.getEntity();
11
12                 BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
13                 StringBuilder sb = new StringBuilder();
14
15                 for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
16                     sb.append(temp);
17                 }
18                 JSONObject object = new JSONObject(sb.toString().trim());
19                 int errorCode = object.getInt("errcode");
20                 if (errorCode == 0) {
21                     return true;
22                 }
23             }
24         } catch (ClientProtocolException e) {
25             // TODO Auto-generated catch block
26             e.printStackTrace();
27         } catch (IOException e) {
28             // TODO Auto-generated catch block
29             e.printStackTrace();
30         } catch (JSONException e) {
31             // TODO Auto-generated catch block
32             e.printStackTrace();
33         }
34         return false;
35     }

返回说明

1 正确的Json返回结果:
2 {
3 "errcode":0,"errmsg":"ok"
4 }
5 错误的Json返回示例:
6 {
7 "errcode":40003,"errmsg":"invalid openid"
8 }

如果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失效的后,需要用户重新授权。

 1 private void refreshAccessToken() {2         String uri = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + ShareUtil.APP_ID + "&grant_type=refresh_token&refresh_token="3                 + refreshToken;4         HttpClient client = new DefaultHttpClient();5         HttpGet get = new HttpGet(URI.create(uri));6         try {7             HttpResponse response = client.execute(get);8             if (response.getStatusLine().getStatusCode() == 200) {9                 BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
10                 StringBuilder builder = new StringBuilder();
11                 for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
12                     builder.append(temp);
13                 }
14                 JSONObject object = new JSONObject(builder.toString().trim());
15                 accessToken = object.getString("access_token");
16                 refreshToken = object.getString("refresh_token");
17                 openID = object.getString("openid");
18                 expires_in = object.getLong("expires_in");
19             }
20         } catch (ClientProtocolException e) {
21             // TODO Auto-generated catch block
22             e.printStackTrace();
23         } catch (IOException e) {
24             // TODO Auto-generated catch block
25             e.printStackTrace();
26         } catch (JSONException e) {
27             // TODO Auto-generated catch block
28             e.printStackTrace();
29         }
30     }

返回说明

 1 正确的返回:2 { 3 "access_token":"ACCESS_TOKEN", 4 "expires_in":7200, 5 "refresh_token":"REFRESH_TOKEN", 6 "openid":"OPENID", 7 "scope":"SCOPE" 8 }9 参数                    说明
10 access_token       接口调用凭证
11 expires_in        access_token接口调用凭证超时时间,单位(秒)
12 refresh_token     用户刷新access_token
13 openid           授权用户唯一标识
14 scope          用户授权的作用域,使用逗号(,)分隔
15
16 错误返回样例:
17 {
18 "errcode":40030,"errmsg":"invalid refresh_token"
19 }

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

 

转载于:https://www.cnblogs.com/kenshinobiy/p/8640006.html

详解如何进行第三方App接入微信登录相关推荐

  1. 第三方App接入微信登录 解读

    最近在做一个微信登录功能,发现腾讯的API文档写的实在是让人摸不着头脑,也没有搜到很详细的能让人参考的文章,借此把自己的一点儿使用心得与大家分享,欢迎指正其中的不足之处,谢谢! 准备工作 1.在微信开 ...

  2. 第三方App接入微信登录 解读 (微信开放平台)

    http://www.cnblogs.com/linjunjie/p/6249989.html 微信开放平台  和  微信公众平台  概念不同. 1.首先需要注册微信开放平台,然后获取开发者认证.审批 ...

  3. Android Studio App 接入微信登录

    安卓接入微信登录 微信开发平台获取AppId和AppSecret 开始接入 添加依赖 注册wxApi 登录调用 监听登录回调 注意事项 微信开发平台获取AppId和AppSecret 创建应用 填写对 ...

  4. 微信开发 - 第三方网站接入微信登录、微信支付时,本地 redirect_uri 参数错误导致无法调试的解决方案(微信开放平台)完美解决每次都需要部署到线上测试,在本地使用本地 ip 就能轻松调试

    问题描述 网上的教程都非常乱且无效,本文将站在新手的角度,超级详细的讲解. 本文提供 在微信开放平台,接入微信登录和微信支付时,本文无法调试 redirect_uri 回调错误 的解决方案, 仅需几个 ...

  5. android实现第三方支付,Android开发第三方APP接入微信支付

    前言 在APP中接入微信支付其实很简单,大部分工作主要都是后台完成,客户端只需要调用后台,得到后台返回的字符串后在调用微信的api即可.但是会有些坑,稍不注意就会掉坑里,下面会讲到. 一. 接入流程 ...

  6. 第三方SDK接入--微信

    第三方SDK接入–微信 说明 由于公司的需求,app需要使用微信登录以及分享到微信等功能,近期对微信的第三方登录.分享功能进行了少许研究,并记录如下. 注意点: 1. 需到"微信开放平台&q ...

  7. 极客日报:阿里旗下App接入微信支付;马斯克成世界首富;PostgreSQL 14 RC 1发布

    一分钟速览新闻点! 阿里回应App接入微信支付 抖音起诉知乎名誉侵权 小米上诉"小米穿戴"图形商标被驳回 拼多多.美团已支持众多主流支付渠道 清华AI学生华智冰首次露正脸唱歌 快手 ...

  8. Android 第三方应用接入微信平台(1)

    关键字:微信开放平台   Android第三方应用接入微信 微信平台开放后倒是挺火的,许多第三方应用都想试下接入微信这个平台, 毕竟可以利用微信建立起来的关系链来拓展自己的应用还是挺不错的,可 以节约 ...

  9. Android 第三方应用接入微信平台(2)

    关键字:微信开放平台   Android第三方应用接入微信 微信平台开放后倒是挺火的,许多第三方应用都想试下,毕竟可以利用微信 建立起来的关系链来拓展自己的应用还是挺不错的,可以节约很多在社交方 面的 ...

最新文章

  1. Spring Aop 常见注解和执行顺序
  2. R语言可视化分面图、多变量分组嵌套多水平t检验、可视化多变量分组嵌套多水平分面条形图(faceting bar plot)并添加显著性水平、添加误差条
  3. cocos2d笔记——解析HelloWorldScene
  4. 监控视频长度压缩算法
  5. Ubuntu下串口通信之cutecom
  6. BZOJ2705 [SDOI2012]Longge的问题 欧拉函数
  7. 计算机函授本科题库,计算机应用基础函授本科考试题库
  8. 2-3:套接字(Socket)编程之UDP通信,sockaddr,sockaddr_in,recvfrom,sendto
  9. INSERT INTO SELECT 语句
  10. 通过汉字查找五笔码和拼音
  11. 武汉年会签到,抽奖,摇一摇,微信上墙,互动大屏
  12. ES集群不通,日志报[node-3] not enough master nodes discovered during pinging (found [[Candidate{node={node-3
  13. heroku搭建mysql_在heroku上部署Flask应用程序并将其连接到颚数据库mysql数据库
  14. python can总线_MicroPython教程之TPYBoard v102 CAN总线通信
  15. 在vue项目中使用高德地图JS API
  16. Ubuntu12.04 设置1080P分辨率
  17. 如何显示在网页中显示阿拉伯语言
  18. Foxmail签名和模板的使用
  19. unreal 渲染讲的比较好的材料
  20. Linux之设备操作

热门文章

  1. 中国光纤管理解决方案市场发展分析及十四五规划咨询建议报告2022年版
  2. 一个简单的HTTP通讯的例子,使用了CInternetSession,CHttpConnection,CHttpFile三个类
  3. php layui实现添加input,Layui实现input输入和选择的方法
  4. 随机数排列JAVA_随机数生成器,按排序顺序
  5. 粤桂粤黔谋定现代农业产业园 林裕豪:从玉农业一县一园签约
  6. Angular2入门--架构概览
  7. webapi同时支持post和get报404错误
  8. 20162304 实验三
  9. HDUOJ-----Brave Game
  10. u-boot的nand驱动写过程分析