最近用到过微信用户授权获取用户信息的功能,在这里记录一下。
因为用户授权要用到认证过的服务号才有权限,而线上正在使用公众号,而开发就有些不方便了,这里可以申请一个微信公众测试号。
1.申请一个微信公众测试号
2.配置测试号公网服务器地址
token 可以自己指定,URL就是网站指定地址进行token验证,验证通过就可以使用服务器了
验证代码如下:
#控制器
/**
* 微信Token 验证
*/
public function checkSignature()
{
$signature = request()->input('signature');
$timestamp = request()->input('timestamp');
$nonce = request()->input('nonce');
$echostr = request()->input('echostr');
echo $this->WeChat->checkSignature($signature, $timestamp, $nonce, $echostr);
}
#模型层
/**
* 微信验证签名
* @param $signature
* @param $timestamp
* @param $nonce
* @param $echostr
* @return bool
*/
public function checkSignature($signature, $timestamp, $nonce, $echostr)
{
if (empty($signature) || empty($timestamp) || empty($nonce)) return false;
$token = self::$TOKEN; // 网页上设置的token
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if ($tmpStr == $signature) {
return $echostr;
} else {
return false;
}
}
#路由
Route::any('checkSignature', 'Controller@checkSignature');
3.关注测试号后就可以使用关注的微信号打开授权的页面
4.修改网页授权回调域名
5.网页授权流程分为四步:
(1)引导用户进入授权页面同意授权,获取code
(2)通过code换取网页授权access_token(与基础支持中的access_token不同)
(3)如果需要,开发者可以刷新网页授权access_token,避免过期(可以忽略)
(4)通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
6.具体实现代码
(1)路由
//微信网页授权调试
Route::get('getWeChatCode', 'Controller@getWeChatCode');
//获取微信回调信息
Route::get('weChatCallback', 'Controller@weChatCallback');
?(2)控制器
/**
* 微信网页授权调试
*/
public function getWeChatCode()
{
$object = new WeChat();
$callback_url = request()->input('url');
$res = $object->getCodeUrl($callback_url);
echo "<a href='" . $res . "'>点击</a>";
}
/**
* 获取用户信息
*/
public function weChatCallback()
{
$code = request()->input('code');
$object = new WeChat();
$openInfo = $object->getOpenId($code);
if (isset($openInfo['errcode'])) {
echo '微信授权登录登录失败' . $openInfo['errmsg'];die;
}
$userInfo = $object->getUserInfo($openInfo['access_token'], $openInfo['openid']);
echo '登录用户信息:';
print_r($userInfo);
}
?(3)微信方法
<?php
class WeChat
{
/**
* 微信公众平台微信验证签名
* @var string
*/
protected static $TOKEN = 'xxxxxxxx';
/**
* 微信公众平台appid
* @var string
*/
protected static $appId = 'xxxxxxx';
/**
* 微信公众平台app secret
* @var string
*/
protected static $appSecret = 'xxxxxxxx';
/**
* 微信验证签名
* @param $signature
* @param $timestamp
* @param $nonce
* @param $echostr
* @return bool
*/
public function checkSignature($signature, $timestamp, $nonce, $echostr)
{
if (empty($signature) || empty($timestamp) || empty($nonce)) return false;
$token = self::$TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if ($tmpStr == $signature) {
return $echostr;
} else {
return false;
}
}
/**
* 通过公众平台key获取网页授权页面
* 可通过回调获取code参数
* @param $callback_url:回调地址
* @return string
*/
public function getCodeUrl($callback_url)
{
$callback = urlencode($callback_url);
$AppId = self::$appId;
$get_code_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$AppId}&redirect_uri={$callback}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
return $get_code_url;
}
/**
* 通过公众平台key
* 获取用户openId access_token
* @param $code
* @return bool|string
*/
public function getOpenId($code)
{
$AppId = self::$appId;
$AppSecret = self::$appSecret;
$get_openid_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$AppId}&secret={$AppSecret}&code={$code}&grant_type=authorization_code";
$res = file_get_contents($get_openid_url);
return djson($res);
}
/**
* 获取微信用户信息
* @param $access_token
* @param $openId
* @return bool|mixed
*/
public function getUserInfo($access_token, $openId)
{
$url = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openId}&lang=zh_CN";
$res = $this->linkCurl($url, 'GET');
$res = json_decode($res, true);
return $res;
}
/**
* 请求接口返回内容
* @param $url :请求的URL地址
* @param $method :请求方式POST|GET
* @param $params :请求的参数
* @param $header : 请求头
* @return bool|string
*/
protected function linkCurl($url, $method, $params = array(), $header = array())
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if (strpos("$" . $url, "https://") == 1) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if ($method == "POST") {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
} else if ($params) {
curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params));
}
$response = curl_exec($ch);
if ($response === false) {
return false;
}
curl_close($ch);
return $response;
}
}
7.编辑访问路径,在关注的微信中打开
如果非微信打开:
打开效果
第一次授权显示页面为:
多次授权就会显示以下图片
得到用户信息
注意:
code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
|