關(guān)于網(wǎng)頁授權(quán)回調(diào)域名的說明
1、在微信公眾號請求用戶網(wǎng)頁授權(quán)之前酗昼,開發(fā)者需要先到公眾平臺官網(wǎng)中的“開發(fā) - 接口權(quán)限 - 網(wǎng)頁服務(wù) - 網(wǎng)頁帳號 - 網(wǎng)頁授權(quán)獲取用戶基本信息”的配置選項中仔雷,修改授權(quán)回調(diào)域名舔示。請注意惕稻,這里填寫的是域名(是一個字符串),而不是URL公给,因此請勿加 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 都可以進行OAuth2.0鑒權(quán)防症。但http://pay.qq.com 哎甲、 http://music.qq.com 扑浸、 http://qq.com無法進行OAuth2.0鑒權(quán)
關(guān)于網(wǎng)頁授權(quán)的兩種scope的區(qū)別說明
1喝噪、以snsapi_base為scope發(fā)起的網(wǎng)頁授權(quán),是用來獲取進入頁面的用戶的openid的榴鼎,并且是靜默授權(quán)并自動跳轉(zhuǎn)到回調(diào)頁的晚唇。用戶感知的就是直接進入了回調(diào)頁(往往是業(yè)務(wù)頁面)
2哩陕、以snsapi_userinfo為scope發(fā)起的網(wǎng)頁授權(quán),是用來獲取用戶的基本信息的闽瓢。但這種授權(quán)需要用戶手動同意心赶,并且由于用戶同意過缨叫,所以無須關(guān)注,就可在授權(quán)后獲取該用戶的基本信息销钝。
3琐簇、用戶管理類接口中的“獲取用戶基本信息接口”鸽嫂,是在用戶和公眾號產(chǎn)生消息交互或關(guān)注后事件推送后,才能根據(jù)用戶OpenID來獲取用戶基本信息橡娄。這個接口癣籽,包括其他微信接口滤祖,都是需要該用戶(即openid)關(guān)注了公眾號后匠童,才能調(diào)用成功的塑顺。
關(guān)于網(wǎng)頁授權(quán)access_token和普通access_token的區(qū)別
1严拒、微信網(wǎng)頁授權(quán)是通過OAuth2.0機制實現(xiàn)的,在用戶授權(quán)給公眾號后挤牛,公眾號可以獲取到一個網(wǎng)頁授權(quán)特有的接口調(diào)用憑證(網(wǎng)頁授權(quán)access_token)墓赴,通過網(wǎng)頁授權(quán)access_token可以進行授權(quán)后接口調(diào)用航瞭,如獲取用戶基本信息沧奴;
2长窄、其他微信接口,需要通過基礎(chǔ)支持中的“獲取access_token”接口來獲取到的普通access_token調(diào)用疮绷。
關(guān)于特殊場景下的靜默授權(quán)
關(guān)于特殊場景下的靜默授權(quán)
1冬骚、上面已經(jīng)提到懂算,對于以snsapi_base為scope的網(wǎng)頁授權(quán)计技,就靜默授權(quán)的,用戶無感知舍悯;
2、對于已關(guān)注公眾號的用戶饮醇,如果用戶從公眾號的會話或者自定義菜單進入本公眾號的網(wǎng)頁授權(quán)頁秕豫,即使是scope為snsapi_userinfo馁蒂,也是靜默授權(quán),用戶無感知饵隙。
具體而言沮脖,網(wǎng)頁授權(quán)流程分為四步:
1勺届、引導(dǎo)用戶進入授權(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機制)
第一步:用戶同意授權(quán)槽片,獲取code
參數(shù) | 是否必須 | 說明 |
---|---|---|
appid | 是 | 公眾號的唯一標(biāo)識 |
redirect_uri | 是 | 授權(quán)后重定向的回調(diào)鏈接地址吼肥, 請使用 urlEncode 對鏈接進行處理 |
response_type | 是 | 返回類型窗价,請?zhí)顚慶ode |
scope | 是 | 應(yīng)用授權(quán)作用域体斩,snsapi_base(不彈出授權(quán)頁面漂辐,直接跳轉(zhuǎn)免钻,只能獲取用戶openid)绳慎,snsapi_userinfo(彈出授權(quán)頁面酸员,可通過openid拿到昵稱路召、性別勃刨、所在地波材。并且, 即使在未關(guān)注的情況下身隐,只要用戶授權(quán)廷区,也能獲取其信息 ) |
state | 否 | 重定向后會帶上state參數(shù),開發(fā)者可以填寫a-zA-Z0-9的參數(shù)值贾铝,最多128字節(jié) |
#wechat_redirect | 是 | 無論直接打開還是做頁面302重定向時候隙轻,必須帶此參數(shù) |
第二步:通過code換取網(wǎng)頁授權(quán)access_token
首先請注意,這里通過code換取的是一個特殊的網(wǎng)頁授權(quán)access_token,與基礎(chǔ)支持中的access_token(該access_token用于調(diào)用其他接口)不同垢揩。
如果網(wǎng)頁授權(quán)的作用域為snsapi_base玖绿,則本步驟中獲取到網(wǎng)頁授權(quán)access_token的同時,也獲取到了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 | 是 | 公眾號的唯一標(biāo)識 |
secret | 是 | 公眾號的appsecret |
code | 是 | 填寫第一步獲取的code參數(shù) |
grant_type | 是 | 填寫為authorization_code |
返回說明:
正確時返回的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)用憑證超時時間,單位(秒) |
refresh_token | 用戶刷新access_token |
openid | 用戶唯一標(biāo)識锋勺,請注意蚀瘸,在未關(guān)注公眾號時,用戶訪問公眾號的網(wǎng)頁庶橱,也會產(chǎn)生一個用戶和公眾號唯一的OpenID |
scope | 用戶授權(quán)的作用域贮勃,使用逗號(,)分隔 |
示例代碼:
<?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;
// 請求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;
}