如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。

关于OAuth2.0的说明

官方网站:http://oauth.net/   http://oauth.net/2/

权威定义:OAuth is An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.

OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站、移动或桌面应用上存储的私密的资源(如用户个人信息、照片、视频、联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth 2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。

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

新浪微博API目前也使用OAuth 2.0。

微信公众平台OAuth2.0授权

大体流程如下图:

用户请求

用户首先请求第三方网页

第三方服务器处理

第三方服务器获取用户请求后会进行判断,是否需要获取code(正常请求肯定是需要code的,这里我们可以参考一下官方JsApiPay的mode,来看获取openid的大体流程)

  1 <?php
  2 require_once "../lib/WxPay.Api.php";
  3 /**
  4  *
  5  * JSAPI支付实现类
  6  * 该类实现了从微信公众平台获取code、通过code获取openid和access_token、
  7  * 生成jsapi支付js接口所需的参数、生成获取共享收货地址所需的参数
  8  *
  9  * 该类是微信支付提供的样例程序,商户可根据自己的需求修改,或者使用lib中的api自行开发
 10  *
 11  * @author widy
 12  *
 13  */
 14 class JsApiPay
 15 {
 16     /**
 17      *
 18      * 网页授权接口微信服务器返回的数据,返回样例如下
 19      * {
 20      *  "access_token":"ACCESS_TOKEN",
 21      *  "expires_in":7200,
 22      *  "refresh_token":"REFRESH_TOKEN",
 23      *  "openid":"OPENID",
 24      *  "scope":"SCOPE",
 25      *  "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
 26      * }
 27      * 其中access_token可用于获取共享收货地址
 28      * openid是微信支付jsapi支付接口必须的参数
 29      * @var array
 30      */
 31     public $data = null;
 32
 33     /**
 34      *
 35      * 通过跳转获取用户的openid,跳转流程如下:
 36      * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
 37      * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code
 38      *
 39      * @return 用户的openid
 40      */
 41     public function GetOpenid()
 42     {
 43         //通过code获得openid
 44         if (!isset($_GET['code'])){
 45             //触发微信返回code码
 46             $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']);
 47             $url = $this->__CreateOauthUrlForCode($baseUrl);
 48             Header("Location: $url");
 49             exit();
 50         } else {
 51             //获取code码,以获取openid
 52             $code = $_GET['code'];
 53             $openid = $this->getOpenidFromMp($code);
 54             return $openid;
 55         }
 56     }
 57
 58     /**
 59      *
 60      * 获取jsapi支付的参数
 61      * @param array $UnifiedOrderResult 统一支付接口返回的数据
 62      * @throws WxPayException
 63      *
 64      * @return json数据,可直接填入js函数作为参数
 65      */
 66     public function GetJsApiParameters($UnifiedOrderResult)
 67     {
 68         if(!array_key_exists("appid", $UnifiedOrderResult)
 69         || !array_key_exists("prepay_id", $UnifiedOrderResult)
 70         || $UnifiedOrderResult['prepay_id'] == "")
 71         {
 72             throw new WxPayException("参数错误");
 73         }
 74         $jsapi = new WxPayJsApiPay();
 75         $jsapi->SetAppid($UnifiedOrderResult["appid"]);
 76         $timeStamp = time();
 77         $jsapi->SetTimeStamp("$timeStamp");
 78         $jsapi->SetNonceStr(WxPayApi::getNonceStr());
 79         $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);
 80         $jsapi->SetSignType("MD5");
 81         $jsapi->SetPaySign($jsapi->MakeSign());
 82         $parameters = json_encode($jsapi->GetValues());
 83         return $parameters;
 84     }
 85
 86     /**
 87      *
 88      * 通过code从工作平台获取openid机器access_token
 89      * @param string $code 微信跳转回来带上的code
 90      *
 91      * @return openid
 92      */
 93     public function GetOpenidFromMp($code)
 94     {
 95         $url = $this->__CreateOauthUrlForOpenid($code);
 96         //初始化curl
 97         $ch = curl_init();
 98         //设置超时
 99         curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
100         curl_setopt($ch, CURLOPT_URL, $url);
101         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
102         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
103         curl_setopt($ch, CURLOPT_HEADER, FALSE);
104         curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
105         if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
106             && WxPayConfig::CURL_PROXY_PORT != 0){
107             curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);
108             curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);
109         }
110         //运行curl,结果以jason形式返回
111         $res = curl_exec($ch);
112         curl_close($ch);
113         //取出openid
114         $data = json_decode($res,true);
115         $this->data = $data;
116         $openid = $data['openid'];
117         return $openid;
118     }
119
120     /**
121      *
122      * 拼接签名字符串
123      * @param array $urlObj
124      *
125      * @return 返回已经拼接好的字符串
126      */
127     private function ToUrlParams($urlObj)
128     {
129         $buff = "";
130         foreach ($urlObj as $k => $v)
131         {
132             if($k != "sign"){
133                 $buff .= $k . "=" . $v . "&";
134             }
135         }
136
137         $buff = trim($buff, "&");
138         return $buff;
139     }
140
141     /**
142      *
143      * 获取地址js参数
144      *
145      * @return 获取共享收货地址js函数需要的参数,json格式可以直接做参数使用
146      */
147     public function GetEditAddressParameters()
148     {
149         $getData = $this->data;
150         $data = array();
151         $data["appid"] = WxPayConfig::APPID;
152         $data["url"] = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
153         $time = time();
154         $data["timestamp"] = "$time";
155         $data["noncestr"] = "1234568";
156         $data["accesstoken"] = $getData["access_token"];
157         ksort($data);
158         $params = $this->ToUrlParams($data);
159         $addrSign = sha1($params);
160
161         $afterData = array(
162             "addrSign" => $addrSign,
163             "signType" => "sha1",
164             "scope" => "jsapi_address",
165             "appId" => WxPayConfig::APPID,
166             "timeStamp" => $data["timestamp"],
167             "nonceStr" => $data["noncestr"]
168         );
169         $parameters = json_encode($afterData);
170         return $parameters;
171     }
172
173     /**
174      *
175      * 构造获取code的url连接
176      * @param string $redirectUrl 微信服务器回跳的url,需要url编码
177      *
178      * @return 返回构造好的url
179      */
180     private function __CreateOauthUrlForCode($redirectUrl)
181     {
182         $urlObj["appid"] = WxPayConfig::APPID;
183         $urlObj["redirect_uri"] = "$redirectUrl";
184         $urlObj["response_type"] = "code";
185         $urlObj["scope"] = "snsapi_base";
186         $urlObj["state"] = "STATE"."#wechat_redirect";
187         $bizString = $this->ToUrlParams($urlObj);
188         return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
189     }
190
191     /**
192      *
193      * 构造获取open和access_toke的url地址
194      * @param string $code,微信跳转带回的code
195      *
196      * @return 请求的url
197      */
198     private function __CreateOauthUrlForOpenid($code)
199     {
200         $urlObj["appid"] = WxPayConfig::APPID;
201         $urlObj["secret"] = WxPayConfig::APPSECRET;
202         $urlObj["code"] = $code;
203         $urlObj["grant_type"] = "authorization_code";
204         $bizString = $this->ToUrlParams($urlObj);
205         return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
206     }
207 }

展开代码

授权

如果需要获取code,第三方服务器会跳转到授权页面

在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认拥有scope参数中的snsapi_base和snsapi_userinfo),引导关注者打开如下页面

请求方法如下:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。

参数说明:

参数 必须 说明
appid 公众号的唯一标识
redirect_uri 授权后重定向的回调链接地址
response_type 返回类型,请填写code
scope 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息
state 重定向后会带上state参数,开发者可以填写任意参数值
#wechat_redirect 直接在微信打开链接,可以不填此参数。做页面302重定向时候,必须带此参数

下图为scope等于snsapi_userinfo时的授权页面:

用户同意授权

用户同意授权将信息发送到微信公众平台,微信公众平台会内部进行授权验证

用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。

code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

获取网页授权

验证通过返回给第三方服务器code

通过code换取网页授权access_token

首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。

请求方法如下:

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

参数说明:

参数 是否必须 说明
appid 公众号的唯一标识
secret 公众号的appsecret
code 填写第一步获取的code参数
grant_type 填写为authorization_code

返回说明:

正确时返回的JSON数据包如下:

{ "access_token":"ACCESS_TOKEN",    "expires_in":7200,    "refresh_token":"REFRESH_TOKEN",    "openid":"OPENID",    "scope":"SCOPE" }

参数说明:

 参数 描述
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
scope 用户授权的作用域,使用逗号(,)分隔

错误时微信会返回JSON数据包如下(示例为Code无效错误):

{"errcode":40029,"errmsg":"invalid code"}

判断access_token过期

如果access_token过期了需要重新刷取access_token(初次使用可以先忽略)

请求方法如下:

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

参数说明:

 参数 是否必须 说明
appid 公众号的唯一标识
grant_type 填写为refresh_token
refresh_token 填写通过access_token获取到的refresh_token参数

拉取用户信息

官方文档有说明,需要scope为snsapi_userinfo

请求方法如下:

http:GET(请使用https协议) https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

参数说明:

参数 描述
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
openid 用户的唯一标识

返回说明

正确时返回的JSON数据包如下:

{    "openid":" OPENID",  " nickname": NICKNAME,   "sex":"1",   "province":"PROVINCE"   "city":"CITY",   "country":"COUNTRY",    "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",  "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" }

参数说明:

 参数 描述
openid 用户的唯一标识
nickname 用户昵称
sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
province 用户个人资料填写的省份
city 普通用户个人资料填写的城市
country 国家,如中国为CN
headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
privilege 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)

错误时微信会返回JSON数据包如下(示例为openid无效):

{"errcode":40003,"errmsg":" invalid openid "}

其他一些细节性的问题请参考官方文档:https://mp.weixin.qq.com/wiki

转载于:https://www.cnblogs.com/bndong/p/6222266.html

微信开发_网页授权获取用户的基本信息相关推荐

  1. 微信开发之网页授权获取用户基本信息

    微信官方文档:网页授权获取用户基本信息 具体而言,网页授权流程分为四步: 1.引导用户进入授权页面同意授权,获取code https://open.weixin.qq.com/connect/oaut ...

  2. Java微信公众号开发之网页授权获取用户基本信息

    本篇博客讲解的网页授权只需要前端传递一个backUrl(回调地址) 到后台接口,后台接口会完成整个授权流程,无需前端做更多工作: 一. 前言 微信公众号开发,需要用到网页授权获取用户信息,通过OAut ...

  3. 微信公众号开发系列-网页授权获取用户基本信息

    OAuth2.0网页授权这个也是在做微信公众平台用到最多的,可以利用授权接口对自己平台内用户进行绑定,实现用户扫描码和微信分享.微信签到.微信商城购物等: 1.高级接口OAuth2.0网页授权设置 a ...

  4. 微信公众号网页授权获取用户信息的流程

    官网文档 网页授权流程分为四步: 引导用户进入授权页面同意授权,获取code 通过 code 换取网页授权access_token(与基础支持中的access_token不同)(我的需求只需要到第二部 ...

  5. 微信接口开发之高级篇系列【网页授权获取用户基本信息】

    PHP微信接口开发之高级篇之网页授权获取用户基本信息 二.WEB开发工具 转载于:https://www.cnblogs.com/tinywan/p/5860981.html

  6. 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息

    第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...

  7. 微信公众号开发之微信网页授权获取用户个人信息

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 一丶概述 微信网页授权 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑 ...

  8. asp.net mvc C# 微信公众号-服务号开发 (用户网页授权获取用户昵称头像信息)...

    参考文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432 一.安装Senparc.Weixin NuGet包 ...

  9. 连小白都能看懂的微信开发之 微信自定义菜单 + 获取网页授权 + 获取用户信息

    微信自定义菜单+获取网页授权+获取用户信息 今天项目需要一个需求,就是添加一个菜单接口,并且还可以获取用于的信息,从而根据用户的信息去做一些业务的查询.通过百度和自己查看文档大致的解决办法如下: 注意 ...

最新文章

  1. 86岁还在录网课:MIT教授Gilbert Strang最新「线性代数」课程上线
  2. 银行背景下分库分表技术选型
  3. @Profile 根据不同环境注入bean
  4. 学习C#中调用COM,后期绑定(以及对WinHttp COM对象的C#封装)
  5. 基础SQL面试题(1)
  6. c#语法之lock 语句
  7. TCP、UDP套接字的数据传输
  8. 多线程篇-NSThread-简单使用
  9. 安装memcached:error while loading shared libraries: libevent-1.4.so.2
  10. mysql组合索引与字段顺序
  11. [Flex]实现Application未初始化前加载自定义配置内容
  12. Layer 引入自定义模块
  13. python xp系统_win XP的系统应该装哪个python的安装包?
  14. 孙玄:转转如何打造AI工程架构体系
  15. APIO2016游记
  16. 灰色预测模型python实例_12-6:数学模型(灰色模型)与Python编程预测
  17. lisp 获取横断面数据_基于Visual LISP全路线横断面数据自动提取
  18. nginx负载均衡 tomcat报异常: parseHost The host [*] is not valid
  19. java中import是什么意思_java中import关键字是什么意思
  20. 《高效能人士的执行4原则 》读后感

热门文章

  1. android loadsvm raw,OpenCV机器学习:Android上利用SVM实现手写体数字识别
  2. 红豆角源码--红豆角系统红豆角APP拼团系统源码分享
  3. 立志做中国市场TOP2,新华三云屏底气何来?
  4. 强化学习1 高斯赛德尔迭代
  5. cvat标注软件入门
  6. 常见的 vue elementUI el的标签总结
  7. 运动生理学:同骨骼肌相比,心肌细胞的收缩特点是什么?
  8. 在马克思手稿中有一道趣味的数学问题:一共有30个人,可能包括男人,女人和小孩。他们在一家饭馆吃饭共花了50先令,其中每个男人花3先令,每个女人花2先令,每个小孩花1先令。请问男人、女人和小孩各几人?
  9. 踩坑系列之 memcache的有效期
  10. 软件随想录:程序员部落酋长Joel谈软件(阮一峰译)-3