前言:
当公司让我做微信的第三方登录时,我就想这个简单啊,下个sdk,调用几个方法就齐活了。结果当我打开微信第三方登录的文档时
简单的页两文档,比起微信支付不知道差到哪里去了,点开资源下载,也没有封装好的php SDK。所有的事情只有我们自己来了。
目录:
- 前期准备
- 开始登录
- 业务逻辑介绍
一.前期准备
- 我们需要申请,一个网站应用,这个都是大同小异,我就不赘述了。当然了还有交300块保护费用,这个也是跑不掉的。
- 获取到app_id和secret,还要设置好回调地址,将数据放到配置当中,我这里使用的tp3.2.3 ,使用其他框架的朋友也无所谓都是一样的
-
拼接出请求code的链接
将下图中框起来的部分替换为我们配置好的数据,最后STATE是个用于安全的令牌可以不要。
注意第三个参数scope,权限范围,我们后续肯定要获取用户信息的,所以我推荐使用snsapi_userinfo
我的选择是将这个拼接好了url直接用于我们站点的微信登录按钮上,这样我们就省去了再重定向的步骤
具体实现我是写了一个公共函数来拼接url,然后再视图页面直接调用这个函数。方法有很多,大家可以自己使用自己的方法。
当我们配置好了之后,我们就可以点击试试
如果是这样的页面的话,那么就没问题了,我们来到了用户授权页面。这里的域名是微信的域名。用户在这里扫码之后确认授权,我们就可以继续下面的步骤。
4.微信回调
这里我们要注意,用户不一定非要授权你的网站,所以我们需要确定用户是否授权。
无论用户是否授权微信都回重定向到我们之前预留的回调地址中,并且带者一个叫code的随机字符串(如果之前拼接url时添写了STATE,也会返回这个数据)。
如果用户没有授权则没有code这个数据,我们就根据这个判断
//获取code
$code = I('get.code');
//如果没有code则返回首页
if (empty($code)) {
$this->redirect(U('/'));
die();
}
二.开始登录
我们根据文档知道,这个code 是用于换取access_token用的。文档提示我们需要使用get方式带着code和app_id和secret来请求token。我们当然不能用重定向这样的方法去获取。所以我们选择比较高效的curl,看过我上一篇笔记的朋友都会知道,微博为我们提供了很强大的sdk,我们只需要条用sdk中的get_accessToken()方法就好了,他已经帮我们把curl写好了。既然腾讯没有这么好的服务,就只有我们自己来了
- 封装自己的curl方法
/**
* @param $url 地址
* @param $method 请求方式
* @param null $postfields post的数据
* @param array $headers 请求头
* @param bool $debug 调试模式
* @return array
*/
private function http($url, $method, $postfields = null, $headers = array(), $debug = false)
{
$ci = curl_init();
/* Curl settings */
curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ci, CURLOPT_TIMEOUT, 30);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
switch ($method) {
case 'POST':
curl_setopt($ci, CURLOPT_POST, true);
if (!empty($postfields)) {
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
$this->postdata = $postfields;
}
break;
}
curl_setopt($ci, CURLOPT_URL, $url);
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ci, CURLINFO_HEADER_OUT, true);
$response = curl_exec($ci);
$http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
if ($debug) {
echo "=====post data======\r\n";
var_dump($postfields);
echo '=====info=====' . "\r\n";
print_r(curl_getinfo($ci));
echo '=====$response=====' . "\r\n";
print_r($response);
}
curl_close($ci);
return array($http_code, $response);
}
当然拉,这个也不是我自己写的,是在tp论坛中发现一个大神写的,我就拿来用咯,返回值是一个数组,第一个元素是状态码,我们都知道200是正确连接的意思,第二个元素就是curl返回的数据
- 请求token
//拼接url
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wxConfig['app_id']}&secret={$wxConfig['app_secret']}&code={$code}&grant_type=authorization_code";
//调用curl方法得到返回值
$result = $this->http($url, 'get');
//判断请求状态是否正确
if ($result[0] == 200) {
//将json数据转换为数组,得到accesstoken等数据
$arr = json_decode($result[1],true);
}
这样我们就获取到了一个包含accessToken的数组
这个数组里面有
- 获取用户数据
其实微信和qq一样,没有多少返回数据,有价值的数据更少。不过谁让他用户多嘛,我们还是得做
我选择得是将获取userInfo封装到模型上,方便调用
//实例化模型,没有用过tp3.2.3的朋友不用太在意,总之就是实例化模型就对了
$synModel = D('SyncLogin');
//调用模型上的wechat方法,传入我们刚刚获取到的accessToken,openId,refreshToken
$userInfo = $synModel->wechat($arr['access_token'], $arr['openid'],$arr['refresh_token']);
下面我们看下获取用户信息的方法
/**
* 微信获取用户数据
* @param $token
* @param $openid
* @param $refresh_token
* @return array
*/
public function wechat($token, $openid, $refresh_token)
{
//拼接获取用户信息的url
$url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $token . '&openid=' . $openid;
//发送curl请求,获取返回数据
$result = $this->http($url, 'get');
//判断请求状态
if ($result[0] == 200) {
//将返回的数据整理成数组
$arr = json_decode($result[1], true);
//如果数组中含有键名为errcode,且值等于41001,则说明token过期
if (array_key_exists('errcode', $arr) && $arr['errcode'] == 41001) {
//调用刷新token方法,并返回
return $this->refreshToken($refresh_token);
} else {
//没有过期则返回用户的信息
return $arr;
}
} else {
//请求失败
return false;
}
}
刚才的代码中有用到一个刷新token的方法,这个和获取token大同小异,同样是微信提供的接口,我们配置好了url直接curl访问就是了
/**
* 刷新token
* @param $refresh_token
* @return bool|mixed
*/
public function refreshToken($refresh_token)
{
//获取配置文件的中的数据,没用过的没关系,就是获取配置文件中的配置
$wxConfig = C('WX_LOGIN');
$url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=' . $wxConfig['app_id'] . '&grant_type=refresh_token&refresh_token=' . $refresh_token;
$result = $this->http($url, 'get');
if ($result[0] == 200) {
return json_decode($result[1], true);
} else {
return false;
}
}
三. 业务逻辑
这样我们就获取到了微信用户的用户数据了,剩下的其实就是属于业务逻辑了,我就不贴代码了。每个公司的业务逻辑都有可能不一样。我就介绍下思路,供大家参考
好了,本次微信第三方登录的介绍了就写到这里了,如果有什么地方不对,希望大神指正.谢谢
以上