關(guān)于網(wǎng)頁授權(quán)回調(diào)域名的說明
1、在微信公眾號(hào)請(qǐng)求用戶網(wǎng)頁授權(quán)之前,開發(fā)者需要先到公眾平臺(tái)官網(wǎng)中的“開發(fā) - 接口權(quán)限 - 網(wǎng)頁服務(wù) - 網(wǎng)頁帳號(hào) - 網(wǎng)頁授權(quán)獲取用戶基本信息”的配置選項(xiàng)中,修改授權(quán)回調(diào)域名。請(qǐng)注意,這里填寫的是域名(是一個(gè)字符串),而不是URL,因此請(qǐng)勿加 http:// 等協(xié)議頭;
2、授權(quán)回調(diào)域名配置規(guī)范為全域名,比如需要網(wǎng)頁授權(quán)的域名為:www.qq.com,配置以后此域名下面的頁面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以進(jìn)行OAuth2.0鑒權(quán)。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com無法進(jìn)行OAuth2.0鑒權(quán)
關(guān)于網(wǎng)頁授權(quán)的兩種scope的區(qū)別說明
1、以snsapi_base為scope發(fā)起的網(wǎng)頁授權(quán),是用來獲取進(jìn)入頁面的用戶的openid的,并且是靜默授權(quán)并自動(dòng)跳轉(zhuǎn)到回調(diào)頁的。用戶感知的就是直接進(jìn)入了回調(diào)頁(往往是業(yè)務(wù)頁面)
2、以snsapi_userinfo為scope發(fā)起的網(wǎng)頁授權(quán),是用來獲取用戶的基本信息的。但這種授權(quán)需要用戶手動(dòng)同意,并且由于用戶同意過,所以無須關(guān)注,就可在授權(quán)后獲取該用戶的基本信息。
3、用戶管理類接口中的“獲取用戶基本信息接口”,是在用戶和公眾號(hào)產(chǎn)生消息交互或關(guān)注后事件推送后,才能根據(jù)用戶OpenID來獲取用戶基本信息。這個(gè)接口,包括其他微信接口,都是需要該用戶(即openid)關(guān)注了公眾號(hào)后,才能調(diào)用成功的。
關(guān)于網(wǎng)頁授權(quán)access_token和普通access_token的區(qū)別
1、微信網(wǎng)頁授權(quán)是通過OAuth2.0機(jī)制實(shí)現(xiàn)的,在用戶授權(quán)給公眾號(hào)后,公眾號(hào)可以獲取到一個(gè)網(wǎng)頁授權(quán)特有的接口調(diào)用憑證(網(wǎng)頁授權(quán)access_token),通過網(wǎng)頁授權(quán)access_token可以進(jìn)行授權(quán)后接口調(diào)用,如獲取用戶基本信息;
2、其他微信接口,需要通過基礎(chǔ)支持中的“獲取access_token”接口來獲取到的普通access_token調(diào)用。
關(guān)于特殊場景下的靜默授權(quán)
關(guān)于特殊場景下的靜默授權(quán)
1、上面已經(jīng)提到,對(duì)于以snsapi_base為scope的網(wǎng)頁授權(quán),就靜默授權(quán)的,用戶無感知;
2、對(duì)于已關(guān)注公眾號(hào)的用戶,如果用戶從公眾號(hào)的會(huì)話或者自定義菜單進(jìn)入本公眾號(hào)的網(wǎng)頁授權(quán)頁,即使是scope為snsapi_userinfo,也是靜默授權(quán),用戶無感知。
具體而言,網(wǎng)頁授權(quán)流程分為四步:
1、引導(dǎo)用戶進(jìn)入授權(quán)頁面同意授權(quán),獲取code
2、通過code換取網(wǎng)頁授權(quán)access_token(與基礎(chǔ)支持中的access_token不同)
3、如果需要,開發(fā)者可以刷新網(wǎng)頁授權(quán)access_token,避免過期
4、通過網(wǎng)頁授權(quán)access_token和openid獲取用戶基本信息(支持UnionID機(jī)制)
第一步:用戶同意授權(quán),獲取code
| 參數(shù) | 是否必須 | 說明 |
|---|---|---|
| appid | 是 | 公眾號(hào)的唯一標(biāo)識(shí) |
| redirect_uri | 是 | 授權(quán)后重定向的回調(diào)鏈接地址, 請(qǐng)使用 urlEncode 對(duì)鏈接進(jìn)行處理 |
| response_type | 是 | 返回類型,請(qǐng)?zhí)顚慶ode |
| scope | 是 | 應(yīng)用授權(quán)作用域,snsapi_base(不彈出授權(quán)頁面,直接跳轉(zhuǎn),只能獲取用戶openid),snsapi_userinfo(彈出授權(quán)頁面,可通過openid拿到昵稱、性別、所在地。并且, 即使在未關(guān)注的情況下,只要用戶授權(quán),也能獲取其信息 ) |
| state | 否 | 重定向后會(huì)帶上state參數(shù),開發(fā)者可以填寫a-zA-Z0-9的參數(shù)值,最多128字節(jié) |
| #wechat_redirect | 是 | 無論直接打開還是做頁面302重定向時(shí)候,必須帶此參數(shù) |
第二步:通過code換取網(wǎng)頁授權(quán)access_token
首先請(qǐng)注意,這里通過code換取的是一個(gè)特殊的網(wǎng)頁授權(quán)access_token,與基礎(chǔ)支持中的access_token(該access_token用于調(diào)用其他接口)不同。
如果網(wǎng)頁授權(quán)的作用域?yàn)閟nsapi_base,則本步驟中獲取到網(wǎng)頁授權(quán)access_token的同時(shí),也獲取到了openid,snsapi_base式的網(wǎng)頁授權(quán)流程即到此為止。
鏈接: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數(shù)說明:
| 參數(shù) | 是否必須 | 說明 |
|---|---|---|
| appid | 是 | 公眾號(hào)的唯一標(biāo)識(shí) |
| secret | 是 | 公眾號(hào)的appsecret |
| code | 是 | 填寫第一步獲取的code參數(shù) |
| grant_type | 是 | 填寫為authorization_code |
返回說明:
正確時(shí)返回的JSON數(shù)據(jù)包如下:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
| 參數(shù) | 描述 |
|---|---|
| access_token | 網(wǎng)頁授權(quán)接口調(diào)用憑證,注意:此access_token與基礎(chǔ)支持的access_token不同 |
| expires_in | access_token接口調(diào)用憑證超時(shí)時(shí)間,單位(秒) |
| refresh_token | 用戶刷新access_token |
| openid | 用戶唯一標(biāo)識(shí),請(qǐng)注意,在未關(guān)注公眾號(hào)時(shí),用戶訪問公眾號(hào)的網(wǎng)頁,也會(huì)產(chǎn)生一個(gè)用戶和公眾號(hào)唯一的OpenID |
| scope | 用戶授權(quán)的作用域,使用逗號(hào)(,)分隔 |
示例代碼:
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/8/6
* Time: 22:41
*/
namespace app\index\controller;
use think\Controller;
class Wechat extends Controller
{
protected $accessTokenUrl = 'https://api.weixin.qq.com/cgi-bin/token';
protected $wechatAuthCodeUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize?';
protected $userOpenIdUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token?';
protected $appId;
protected $secret;
protected $code;
protected $openId;
/**
* 加載微信配置
*/
protected function _initialize(){
$this->appId = config('wechat.appId');
$this->secret = config('wechat.secret');
}
/**
* 作用:格式化參數(shù),簽名過程需要使用
* @param $paraMap
* @param $urlencode
* @return bool|string
*/
protected function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v)
{
if($urlencode)
{
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
$reqPar = '';
if (strlen($buff) > 0)
{
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
}
/**
* 網(wǎng)頁授權(quán)獲取用戶openId -- 1.獲取授權(quán)code url
*/
public function getWechatAuthCode(){
// 獲取來源地址
$url = get_url();
// 獲取code
$urlObj["appid"] = $this->appId;
$urlObj["redirect_uri"] = "$url";
$urlObj["response_type"] = "code";
$urlObj["scope"] = "snsapi_base";
$urlObj["state"] = "STATE"."#wechat_redirect";
$bizString = $this->formatBizQueryParaMap($urlObj, false);
$codeUrl = $this->wechatAuthCodeUrl.$bizString;
return $codeUrl;
}
/**
* 網(wǎng)頁授權(quán)獲取用戶openId -- 2.獲取openid
* @return mixed
*/
public function getUserOpenId(){
if (!isset($_GET['code']))
{
$codeUrl = $this->getWechatAuthCode();
Header("Location: $codeUrl");
die;
}else{
$code = $_GET['code'];
$this->code = $code;
// 請(qǐng)求openid
$param = [
'appid' => $this->appId,
'secret' => $this->secret,
'code' => $this->code,
'grant_type'=> "authorization_code",
];
$data = httpGuzzle('get',$this->userOpenIdUrl,$param);
//取出openid
$this->openId = $data['openid'];
return $this->openId;
}
}
}
/**
* 獲取來源地址
* @return string
*/
function get_url() {
//獲取來源地址
$url = "http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
return $url;
}
注意:記得配置接口回調(diào)域名哦~

