获取用户Openid

微信公众号开发 ---- tp5 微信公众号静默授权获取用户openid

 

关于网页授权回调域名的说明

1、在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头;

2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.htmlhttp://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.comhttp://music.qq.comhttp://qq.com无法进行OAuth2.0鉴权

关于网页授权的两种scope的区别说明

1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)

2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

关于网页授权access_token和普通access_token的区别

1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;

2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。
关于特殊场景下的静默授权

关于特殊场景下的静默授权

1、上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;

2、对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。

具体而言,网页授权流程分为四步:

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

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

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

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

第一步:用户同意授权,获取code

链接:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
参数说明:

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

第二步:通过code换取网页授权access_token

首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。
如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。
链接: 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 用户授权的作用域,使用逗号(,)分隔
 

示例代码:

复制代码
  1 <?php
  2 /**
  3  * Created by PhpStorm.
  4  * User: Administrator
  5  * Date: 2018/8/6
  6  * Time: 22:41
  7  */
  8 
  9 namespace app\index\controller;
 10 use think\Controller;
 11 
 12 class Wechat extends Controller
 13 {
 14     protected $accessTokenUrl = 'https://api.weixin.qq.com/cgi-bin/token';
 15     protected $wechatAuthCodeUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize?';
 16     protected $userOpenIdUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token?';
 17 
 18     protected $appId;
 19     protected $secret;
 20     protected $code;
 21     protected $openId;
 22 
 23     /**
 24      * 加载微信配置
 25      */
 26     protected function _initialize(){
 27         $this->appId = config('wechat.appId');
 28         $this->secret = config('wechat.secret');
 29     }
 30     
 31     /**
 32      * 作用:格式化参数,签名过程需要使用
 33      * @param $paraMap
 34      * @param $urlencode
 35      * @return bool|string
 36      */
 37     protected function formatBizQueryParaMap($paraMap, $urlencode)
 38     {
 39         $buff = "";
 40         ksort($paraMap);
 41         foreach ($paraMap as $k => $v)
 42         {
 43             if($urlencode)
 44             {
 45                 $v = urlencode($v);
 46             }
 47             $buff .= $k . "=" . $v . "&";
 48         }
 49         $reqPar = '';
 50         if (strlen($buff) > 0)
 51         {
 52             $reqPar = substr($buff, 0, strlen($buff)-1);
 53         }
 54         return $reqPar;
 55     }
 56 
 57     /**
 58      * 网页授权获取用户openId -- 1.获取授权code url
 59      */
 60     public function getWechatAuthCode(){
 61         // 获取来源地址
 62         $url = get_url();
 63 
 64         // 获取code
 65         $urlObj["appid"] = $this->appId;
 66         $urlObj["redirect_uri"] = "$url";
 67         $urlObj["response_type"] = "code";
 68         $urlObj["scope"] = "snsapi_base";
 69         $urlObj["state"] = "STATE"."#wechat_redirect";
 70         $bizString = $this->formatBizQueryParaMap($urlObj, false);
 71         $codeUrl =  $this->wechatAuthCodeUrl.$bizString;
 72 
 73         return $codeUrl;
 74     }
 75 
 76     /**
 77      * 网页授权获取用户openId -- 2.获取openid
 78      * @return mixed
 79      */
 80     public function getUserOpenId(){
 81         if (!isset($_GET['code']))
 82         {
 83             $codeUrl = $this->getWechatAuthCode();
 84             Header("Location: $codeUrl");
 85             die;
 86         }else{
 87             $code = $_GET['code'];
 88             $this->code = $code;
 89 
 90             // 请求openid
 91             $param = [
 92                 'appid'     =>  $this->appId,
 93                 'secret'    =>  $this->secret,
 94                 'code'      =>  $this->code,
 95                 'grant_type'=>  "authorization_code",
 96             ];
 97 
 98             $data = httpGuzzle('get',$this->userOpenIdUrl,$param);
 99 
100             //取出openid
101             $this->openId = $data['openid'];
102             return $this->openId;
103         }
104     }
105 
106 }
复制代码
复制代码
1 /**
2  * 获取来源地址
3  * @return string
4  */
5 function get_url() {
6     //获取来源地址
7     $url = "http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
8     return $url;
9 }
复制代码

注意:记得配置接口回调域名哦~

亲测后补充:httpGuzzle插件没有的 可以用原生的curl代替

//            $data = httpGuzzle('get',$this->userOpenIdUrl,$param);
// 替换成
$user_info = curl($this->userOpenIdUrl.http_build_query($param).'&lang=zh_CN');
$data = json_decode($user_info);
$this->openId = $data->openid;

在common公共文件里面加入curl

复制代码
 1 if (!function_exists('curl')) {
 2 
 3     // php CURL请求
 4     function curl($url, $post = false)
 5     {
 6         $ch = curl_init();
 7         curl_setopt($ch, CURLOPT_URL, $url);
 8         curl_setopt($ch, CURLOPT_HEADER, 0);
 9         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
10         if ($post) {
11             curl_setopt($ch, CURLOPT_POST, 1);
12             curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
13         }
14         $result = curl_exec($ch);
15         curl_close($ch);
16         return $result;
17     }
18 
19 }
复制代码

 

 

 

 

 

 

 

 

转载于简书
作者:红尘一落君莫笑
链接:https://www.jianshu.com/p/815d4c95b002
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
$data = httpGuzzle('get',$this->userOpenIdUrl,$param);
posted @   微不足道小学生  阅读(1489)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示