微信公众号开发(十二)OAuth2.0网页授权

时间:2023-02-25 15:05:13

OAuth允许用户提供一个令牌,而不是用户名和密码来访问它们存放在特定服务器上的数据,每一个令牌授权一个特定的网站在特定时段内访问特定的资源。

授权过程如下:

1、引导用户进入授权页面同意授权,获取code

2、通过code换取网页授权access_token(与基础支持中的access_token不同)

3、如果需要,开发者可以刷新网页授权access_token,避免过期

4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

1、配置授权回调页面域名
在测试号权限列表中找到OAuth2.0网页授权,然后点击修改,填写自己的域名,注意不能带http://,如果通过,会提示“通过安全检测”的字样。
微信公众号开发(十二)OAuth2.0网页授权
微信公众号开发(十二)OAuth2.0网页授权
2、用户授权获取code
接口:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

scope的两种区别:
snsapi_base:不弹出授权页面,直接跳转,只能获取用户openid
snsapi_userinfo:弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息。



redirect_uri:授权后重定向的回调链接地址,请使用urlencode对链接进行处理。



尤其注意:由于授权操作安全等级较高,所以在发起授权请求时,微信会对授权链接做正则强匹配校验,如果链接的参数顺序不对,授权页面将无法正常访问。



在根目录下新建一个文件夹oauth,并在该文件夹下新建oauth2.php。该文件就是,接口中redirect_uri域名回调页面。

具体获取code的方法步骤是:提供用户请求授权页面的URL,也就是以上的接口,用户点击授权页面URL向服务器发起请求,服务器询问用户是否同意(scope为snsapi_base时无此步骤),用户同意(scope为snsapi_base时无此步骤),服务器将code通过回调传给公众账号开发者。

这里我们只是简单的输出以下code。
oauth2.php
<?php
if (isset($_GET['code'])){
echo "code:".$_GET['code']."<br>";
echo "state:".$_GET["state"];
}else {
echo "no code";
}
然后在index.php中向用户发送授权URL,如下所示。
index.php
<?php
@header('Content-type: text/html;charset=UTF-8');
//设置时区
date_default_timezone_set("Asia/Shanghai");
//定义TOKEN常量,这里的"weixin"就是在公众号里配置的TOKEN require_once("Utils.php");
//打印请求的URL查询字符串到query.xml
Utils::traceHttp(); $wechatObj = new wechatCallBackapiTest();
$wechatObj->responseMsg(); class wechatCallBackapiTest
{
public function responseMsg()
{
//获取post过来的数据,它一个XML格式的数据
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
//将数据打印到log.xml
Utils::logger($postStr);
if (!empty($postStr)) {
//将XML数据解析为一个对象
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$RX_TYPE = trim($postObj->MsgType);
//消息类型分离
switch($RX_TYPE)
{
case "text":
$result = $this->receiveText($postObj);
break;
default:
$result = "";
break;
}
Utils::logger($result, '公众号');
echo $result;
}else {
echo "";
exit;
}
} private function receiveText($object)
{
$appid = "wx07fff9c79a410b69";
$redirect_uri = urlencode("http://weiweiyi.duapp.com/oauth/oauth2.php"); $keyword = trim($object->Content);
if(strstr($keyword, "base")){
$url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=".
"$redirect_uri&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
$content = "用户授权snsapi_base实现:<a href='$url'>单击这里体验OAuth授权</a>";
}else if (strstr($keyword, "userinfo")){
$url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=".
"$redirect_uri&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect";
$content = "用户授权snsapi_userInfo实现:<a href='$url'>单击这里体验OAuth授权</a>";
}else{
$content = "";
}
$result = $this->transmitText($object, $content);
return $result;
}
/**
* 回复文本消息
*/
private function transmitText($object, $content)
{
$xmlTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime><![CDATA[%s]]></CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
$result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), $content);
return $result;
}
}

向公众号分别发送“base”和"baseInfo",则返回如图所示:
微信公众号开发(十二)OAuth2.0网页授权

点击base链接后,直接重定向到oauth2.php页面,可以看到返回的参数中不仅有code,还返回了url中填写的state字段。
微信公众号开发(十二)OAuth2.0网页授权


点击userinfo,则先返回如下页面,需要用户点击“确认”后才能重定向到oauth2.php。
微信公众号开发(十二)OAuth2.0网页授权
3、使用code换取access_token
如果网页授权作用域是snsapi_base,则本步骤获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程到此为止。注意这里的access_token和基础接口中的access_token不同。
接口:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code。
get_token.php
<?php
@header('Content-type: text/plain;charset=UTF-8');
require_once("../Utils.php"); $appid = "wx07fff9c79a410b69";
$appsecret = "092c0c0c5bd62f66b76ad241612915fb";
$code = "0016Q5kn0zdDFp1E3rjn0VUjkn06Q5km"; $url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
."appid=$appid&secret=$appsecret&code=$code&grant_type=authorization_code";
$result = Utils::https_request($url);
echo $result;

如果是base,授权流程到此结束,返回:

{
"access_token": "b3e1GZdT1E-sjKzeKRCr9XUE6IQglkBBxrFXdsmZ8DVW4O5t16EXbIxCoob6pGXwA5Z9JubOZnIytGcM5xC20g",
"expires_in": 7200,
"refresh_token": "yJkiFmmRVq5Kst6PiZpwGPvJh0bcegccx-KFIZEIwYKRmdiLC5dG8-iMRkjl1Stf8cSrHjDauzZtEGNHlnGckA",
"openid": "o4WmZ0h-4huBUVQUczx2ezaxIL9c",
"scope": "snsapi_base"
}

如果是userinfo,返回:

{
"access_token": "iUIP_RnPmjVICZtmq6fFRcslRD1yJax3IkeT_fXKFlDv5W_9y5JS4Z4QgC1W33Qi2BbQ5pWLWt-6LYT7u1Egvg",
"expires_in": 7200,
"refresh_token": "rKwY7NF0BqfSpLVwmVO-htyvlrFWQVRmCdimoaLG2JiHz8wEJZ2H7fcQ5wtJylixBt-dCENgasbaSs8_7M-Kmw",
"openid": "o4WmZ0h-4huBUVQUczx2ezaxIL9c",
"scope": "snsapi_userinfo"
}
4、刷新access_token(可选)
由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。
接口:https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN。
get_refresh_token.php
<?php
@header('Content-type: text/plain;charset=UTF-8');
require_once("../Utils.php"); $appid = "wx07fff9c79a410b69";
$appsecret = "092c0c0c5bd62f66b76ad241612915fb";
$refresh_token = "rKwY7NF0BqfSpLVwmVO-htyvlrFWQVRmCdimoaLG2JiHz8wEJZ2H7fcQ5wtJylixBt-dCENgasbaSs8_7M-Kmw"; $url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?"
."appid=$appid&grant_type=refresh_token&refresh_token=$refresh_token";
$result = Utils::https_request($url);
echo $result;

返回:

{
"openid": "o4WmZ0h-4huBUVQUczx2ezaxIL9c",
"access_token": "iUIP_RnPmjVICZtmq6fFRcslRD1yJax3IkeT_fXKFlDv5W_9y5JS4Z4QgC1W33Qi2BbQ5pWLWt-6LYT7u1Egvg",
"expires_in": 7200,
"refresh_token": "rKwY7NF0BqfSpLVwmVO-htyvlrFWQVRmCdimoaLG2JiHz8wEJZ2H7fcQ5wtJylixBt-dCENgasbaSs8_7M-Kmw",
"scope": "snsapi_base,snsapi_userinfo,"
}
5、使用access_token获取用户信息
接口:https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN。
get_userinfo.php
<?php
@header('Content-type: text/plain;charset=UTF-8');
require_once("../Utils.php"); $access_token = "iUIP_RnPmjVICZtmq6fFRcslRD1yJax3IkeT_fXKFlDv5W_9y5JS4Z4QgC1W33Qi2BbQ5pWLWt-6LYT7u1Egvg";
$openid = "o4WmZ0h-4huBUVQUczx2ezaxIL9c"; $url = "https://api.weixin.qq.com/sns/userinfo?"
."access_token=$access_token&openid=$openid&lang=zh_CN ";
$result = Utils::https_request($url);
echo $result;

返回:

{
"openid": "o4WmZ0h-4huBUVQUczx2ezaxIL9c",
"nickname": "Promise",
"sex": 1,
"language": "zh_CN",
"city": "",
"province": "",
"country": "",
"headimgurl": "http://wx.qlogo.cn/mmopen/vi_32/um6ptBDhpau47ctyJHMakZgyHJsYHzjMfouyWqP6DNxNEPLf2uk6V6TBNnsbanrUcABJiaEa74W8VB7JRk9k0kg/0",
"privilege": []
}

授权过程到此结束。



下面来个完整版的,新建一个oauth_complete.php文件。

将index.php中重定向url改为:$redirect_uri = urlencode("http://weiweiyi.duapp.com/oauth/oauth_complete.php");
oauth.complete.php
<?php

@header('Content-type: text/plain;charset=UTF-8');
require_once("../Utils.php");
$code = $_GET["code"];
$userinfo = getUserInfo($code);
echo $userinfo; function getUserInfo($code)
{
$appid = "wx07fff9c79a410b69";
$appsecret = "092c0c0c5bd62f66b76ad241612915fb"; //根据code获得access_token
$access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
."appid=$appid&secret=$appsecret&code=$code&grant_type=authorization_code";
$access_token_json = Utils::https_request($access_token_url);
$access_token_array = json_decode($access_token_json, true);
//access_token
$access_token = $access_token_array["access_token"];
//openid
$openid = $access_token_array["openid"]; //根据access_token和openid获得用户信息
$userinfo_url = "https://api.weixin.qq.com/sns/userinfo?"
."access_token=$access_token&openid=$openid&lang=zh_CN ";
$userinfo_json = Utils::https_request($userinfo_url);
return $userinfo_json;
}

注意:获取的code只能使用一次,超过一次会报40163的错误,这时会获取不到access_token。

如果不是官方微信网页,会弹出以下界面:
微信公众号开发(十二)OAuth2.0网页授权
其实在这之前已经发送了一次请求,点击“继续访问”实际上相当于第二次访问该页面,所以code也是第二次使用,会报错。







微信公众号开发(十二)OAuth2.0网页授权的更多相关文章

  1. 【微信公众号开发】【8】网页授权获取用户基本信息(OAuth 2&period;0)

    前言: 1,在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名. 请注意,这 ...

  2. Java微信公众平台开发&lpar;十二&rpar;--微信JSSDK的使用

    在前面的文章中有介绍到我们在微信web开发过程中常常用到的 [微信JSSDK中Config配置],但是我们在真正的使用中我们不仅仅只是为了配置Config而已,而是要在我们的项目中真正去使用微信JS- ...

  3. Java微信公众平台开发&lpar;十二&rpar;--微信用户信息的获取

    转自:http://www.cuiyongzhi.com/post/56.html 前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信 ...

  4. nodejs vue 微信公众号开发(二)申请微信测试号

    1.打开微信测试公众号开发平台http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 扫码登陆

  5. 微信公众平台开发,模板消息,网页授权,微信JS-SDK,二维码生成(4)

    微信公众平台开发,模板消息,什么是模板消息,模板消息接口指的是向用户发送重要的服务通知,只能用于符合场景的要求中去,如信用卡刷卡通知,购物成功通知等等.不支持广告营销,打扰用户的消息,模板消息类有固定 ...

  6. 微信公众号开发(二)获取access&lowbar;token

    参考:https://www.cnblogs.com/liuhongfeng/p/4848851.html 一:介绍. 接口调用请求说明 http请求方式: GET https://api.weixi ...

  7. 微信公众号开发(二)获取AccessToken、jsapi&lowbar;ticket

    Access Token 在微信公众平台接口开发中,Access Token占据了一个很重要的地位,相当于进入各种接口的钥匙,拿到这个钥匙才有调用其他各种特殊接口的权限. access_token是公 ...

  8. thinkphp 实现微信公众号开发(二)--实现自定义菜单

    IndexController.class.php <?php namespace Home\Controller; use Think\Controller; class IndexContr ...

  9. C&num;微信公众号开发 -- (二)验证成为开发者

    接下来就是验证成为开发者了.先来看一下验证的界面及需要填写的信息 在接口配置信息中填写需要处理验证信息的页面或者一般性处理文件,这里以aspx页面为例 URl中的格式为:http://XXX.com/ ...

  10. &period;NET微信公众号开发-5&period;0微信支付

    一.前言 在开始做这个功能之前,我们要做的第一件事情就是思考,如何做这个微信支付,从哪里开始,从哪里入手,官方的sdk说明什么的,有没有什么官方的demo,还有就是老板给我的一些资料齐全不,那些要申请 ...

随机推荐

  1. setAttribute&lpar;&rpar;

    ●节点分为不同的类型:元素节点.属性节点和文本节点等.   ●getElementById()方法将返回一个对象,该对象对应着文档里的一个特定的元素节点.   ●getElementsByTagNam ...

  2. ITextSharp导出PDF表格和图片(C&num;)

    文章主要介绍使用ITextSharp导出PDF表格和图片的简单操作说明,以下为ITextSharp.dll下载链接 分享链接:http://pan.baidu.com/s/1nuc6glj 密码:3g ...

  3. 如何管理和记录 SSIS 各个 Task 的开始执行时间和结束时间以及 Task 中添加&vert;删除&vert;修改的记录数

    开篇语 在这篇日志中 如何在 ETL 项目中统一管理上百个 SSIS 包的日志和包配置框架 我介绍到了包级别的日志管理框架,那么这个主要是针对包这一个层级的 Log 信息,包括包开始执行和结束时间,以 ...

  4. 【转】FFMPEG 库移植到 VC 需要的步骤

    原文:http://blog.csdn.net/leixiaohua1020/article/details/12747899 在VC下使用FFMPEG编译好的库,不仅仅是把.h,.lib,.dll拷 ...

  5. activiti自定义流程之Spring整合activiti-modeler5&period;16实例(三):流程模型列表展示

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  6. Unity 通过Animation实现控件位置的转换

    Unity版本:4.5.1 NGUI版本:3.6.5 参考链接:http://blog.csdn.net/unity3d_xyz/article/details/23035521,作者:CSDN in ...

  7. 退役笔记一&num;MySQL &equals; lambda sql &colon; sql &plus; &amp&semi;&num;39&semi; Source Code 4 Explain Plan &amp&semi;&num;39&semi;

    Mysql 查询运行过程 大致分为4个阶段吧: 语法分析(sql_parse.cc<词法分析, 语法分析, 语义检查 >) >>sql_resolver.cc # JOIN.p ...

  8. Uncaught TypeError&colon; Cannot read property &amp&semi;&num;39&semi;call&amp&semi;&num;39&semi; of undefined jquery&period;validate&period;min&period;js&colon;28

    最近在做表单验证时,,自己写的addMethod 方法总是不起作用.折腾了将近一天. 报告的错误,如下面的 Uncaught TypeError: Cannot read property 'call ...

  9. gnome配置

    1.gome-tweak-tool    gnome调校工具 2.gnome-shell插件(在gome-tweak-tool中) 可在https://extensions.gnome.org/中下载 ...

  10. Merge使用

    Role r = new Role(); r.setName("TEST"); r.setDescription("123"); r.setLevel(2); ...