微信公众平台官方文档就是分为这4步。
1 第一步:用户同意授权,获取code
2 第二步:通过code
换取网页授权access_token
(与基础支持中的access_token不同)
3 第三步:刷新access_token
(如果需要)
4 第四步:拉取用户信息(需scope
为 snsapi_userinfo
)
准备
有一个正常的公众号,接口测试号也行,有个域名。
需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头,而且需要授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com。
第一步:获取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参数对应的授权作用域权限
注意回调域名,访问同意之后,页面将跳转至 redirect_uri/?code=CODE&state=STATE
。这时可以取得code的值,下一步备用,scope
分为snsapi_base
与snsapi_userinfo,snsapi_base
微信授权分为两种:
- 静默授权
- 弹窗授权,需要用户手动同意
两种scope的区别说明 - 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
- 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
第二步:通过code换取网页授权access_token
获取code
后,请求以下链接获取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
这时候会返回一个数据包
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
第三步:刷新access_token(如果需要)
由于access_token
拥有较短的有效期,当access_token
超时后,可以使用refresh_token
进行刷新,refresh_token
有效期为30天,当refresh_token
失效之后,需要用户重新授权。
请求方法
获取第二步的refresh_token
后,请求以下链接获取`access_token:https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
返回数据包
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
第四步:拉取用户信息(需scope为 snsapi_userinfo)
如果网页授权作用域为snsapi_userinfo
,则此时开发者可以通过access_token
和openid
拉取用户信息了。
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
具体应用,以PHP为例
wxLogin.php文件
header("Content-type: text/html; charset=utf-8");
require_once('wxopen.class.php');
$weixin = new class_weixin();
//第一步完成,处于回调页面访问的文件,$_GET['code']获取返回的code值
//第二步:根据code获取access_token和openid
$oauth2_info = $weixin->oauth2_access_token($_GET["code"]);
//第三步:根据access_token和openid获取用户信息
$userinfo = $weixin->oauth2_get_user_info($oauth2_info['access_token'], $oauth2_info['openid']);
var_dump($userinfo);
}
wxopen.class.php文件
define('APPID', "appid");
define('APPSECRET', "appsecret");
class class_weixin
{
var $appid = APPID;
var $appsecret = APPSECRET;
//构造函数,获取Access Token
public function __construct($appid = NULL, $appsecret = NULL)
{
if($appid && $appsecret){
$this->appid = $appid;
$this->appsecret = $appsecret;
}
//1. 本地写入
$res = file_get_contents('access_token.json');
$result = json_decode($res, true);
$this->expires_time = $result["expires_time"];
$this->access_token = $result["access_token"];
if (time() > ($this->expires_time + 3600)){
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$this->appid."&secret=".$this->appsecret;
$res = $this->http_request($url);
$result = json_decode($res, true);
$this->access_token = $result["access_token"];
$this->expires_time = time();
file_put_contents('access_token.json', '{"access_token": "'.$this->access_token.'", "expires_time": '.$this->expires_time.'}');
}
}
//生成OAuth2的Access Token
public function oauth2_access_token($code)
{
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->appsecret."&code=".$code."&grant_type=authorization_code";
$res = $this->http_request($url);
return json_decode($res, true);
}
//获取用户基本信息(OAuth2 授权的 Access Token 获取 未关注用户,Access Token为临时获取)
public function oauth2_get_user_info($access_token, $openid)
{
$url = "https://api.weixin.qq.com/sns/userinfo?access_token=".$access_token."&openid=".$openid."&lang=zh_CN";
$res = $this->http_request($url);
return json_decode($res, true);
}
//HTTP请求(支持HTTP/HTTPS,支持GET/POST)
protected function http_request($url, $data = null)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
//日志记录
private function logger($log_content)
{
if(isset($_SERVER['HTTP_APPNAME'])){ //SAE
sae_set_display_errors(false);
sae_debug($log_content);
sae_set_display_errors(true);
}else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL
$max_size = 500000;
$log_filename = "log.xml";
if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}
file_put_contents($log_filename, date('Y-m-d H:i:s').$log_content."\r\n", FILE_APPEND);
}
}
}
1 条评论
文章已具雏形,需进一步聚焦核心问题。