用户授权也是高级接口那部分内容,只是把它独立出来,这样让整个微信框架条理清晰些,但我们用它首先要在微信后台设置OA2的URL,这里的URL和教程一的有所不同。它是不带http://开头的域名。
首先登陆你的微信后台找到《开发者中心》:
点击修改填入我们的域名如下格式:
好了,最基本要点的OA2要求搞好,下面我们用个WechatAuth类生成一个OA2的URL格式,然后再从服务号里,以链接或者菜单又或者图文,跳到微信内置的WEB里就实现了我们取openid或者授权取用户消息!
例子代码生成snsapi_base或者snsapi_userinfo:
$auth = new WechatAuth(array(
WechatAuth::APP_ID => 'wx32259fc5sd5aac12B',
WechatAuth::APP_SECRET => '7ef73d3c56fcd0d984862ff217d2c648',
));
$url = $auth->getLoginUrl(array(
'redirect_uri' => 'http://www.demo.com/wp/ken',
'scope' => 'snsapi_userinfo' //snsapi_base
));
echo $url;
执行后,我们会得到如下OA2的URL:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx32259fc5d5aac13d&redirect_uri=http%3A%2F%2Fwww.demo.com%2Fwp%2Fken&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirects
然后我们在服务号里以刚才说到的菜单好,链接好 点击转到微信内置的浏览器里,如果你的scope方式为snsapi_userinfo时会弹出授权界面,base时不会弹默认执行后会返回openid:
好了,OA2无非就是让我们生成特定格式的URL,让我们点过去取openid或者用户信息(无论是否关注了你的服务号,只要确认授权),可以运用本站微信的实例有相关OA2的运用或者留言给我!
WechatAuth类:
<?php
/**
* 微信 OAuth2.0授权接口
* Class WechatAuth
*/
class WechatAuth {
const
JSON = 'json',
POST = 'post',
GET = 'get',
APP_ID = 'appid',
APP_SECRET = 'secret',
API_URL_PREFIX = 'https://api.weixin.qq.com/sns';
public
$_error_number = 0,
$_error,
$_APPID,
$_APPSECRET;
protected
$_cache = array(),
$_options,
$_openid,
$_access_token,
$_refresh_token,
$_timeout = 30;
static protected
$_instance;
/**
* 单例模式
* @param array $options
* @return WechatAuth
*/
static public function getInstance(array $options = array()) {
if (empty(self::$_instance)) {
self::$_instance = new WechatAuth($options);
}
return self::$_instance;
}
/**
* @param array $options {WechatAuth::APP_ID:"", WechatAuth::APP_SECRET:""}
*/
public function __construct(array $options = array()) {
$this->_options = array(
'timeout' => $this->_timeout,
);
$_options = array_merge($this->_options, $options);
$this->_APPID = $_options['appid'];
$this->_APPSECRET = $_options['secret'];
$this->_timeout = $_options['timeout'];
}
/**
* 提交请求
* @param $url
* @param array $params
* @param string $type Webchat_API::POST|Webchat_API::GET
* @return bool|mixed
*/
public function request($url, $params = array(), $type = self::POST) {
$ch = curl_init();
if ($type == self::GET) {
$url = $url.'?'.http_build_query($params);
}
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_TIMEOUT => $this->_timeout,
CURLOPT_USERAGENT => 'wordpress_wechat_client/0.1.'.rand(1,6),
CURLOPT_HEADER => 0,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_SSLVERSION => 3,
// CURLOPT_VERBOSE => 1,
));
if ($type == self::POST) {
curl_setopt($ch, CURLOPT_PORT, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
}
if ($type == self::JSON) {
//微信的破接口竟然不支持unicode转义符,违反JSON协定,只能把JSON字符中的unicode转回来
$data = preg_replace('/\\\\u([a-f0-9]{4})/e', "json_decode('\"$0\"', 1)", json_encode($params));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
}
$res = curl_exec($ch);
$this->_error_number = curl_errno($ch);
$this->_error = curl_error($ch);
curl_close($ch);
if ($this->_error_number) {
return false;
}
return $this->parseResult($res);
}
/**
* 处理返回结果
* @param $res
* @return bool|mixed
*/
protected function parseResult($res) {
$res = json_decode($res, true);
if (!empty($res)) {
if (isset($res['errcode']) && $res['errcode']) {
$this->_error_number = $res['errcode'];
$this->_error = $res['errmsg'];
return false;
}
return $res;
}
return false;
}
/**
* 获取当前URL
* @return string
*/
static public function getCurrentUrl() {
$pageURL = 'http';
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {
$pageURL .= "s";
}
$pageURL .= "://";
if (isset($_SERVER['SERVER_PORT']) && $_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
} else {
if(isset($_SERVER["SERVER_NAME"]) && isset($_SERVER["REQUEST_URI"]))
$pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
}
return $pageURL;
}
/**
* 获取访问token
* @param bool $refresh 是否强制刷新
* @return bool|mixed
*/
public function getAuthAccessToken($refresh = false) {
$code = isset($_GET['code']) ? $_GET['code'] : '';
$state = isset($_GET['state']) ? $_GET['state'] : '';
$cache = $this->cache('auth_access_token');
if ($cache && ! $refresh) {
return array('access_token' => $cache, 'code' => $code, 'state' => $state);
}
$res = $this->request(self::API_URL_PREFIX.'/oauth2/access_token', array(
self::APP_ID => $this->_APPID,
self::APP_SECRET => $this->_APPSECRET,
'code' => $code,
'grant_type' => 'authorization_code',
), self::GET);
if ($res) {
$this->cache('auth_access_token', $res['access_token']);
$this->cache('auth_refresh_token', $res['refresh_token']);
$this->cache('auth_openid', $res['openid']);
} else {
if ($this->_error_number == 42001) {
return $this->refreshAccessToken();
}
}
return array('access_token' => $res['access_token'], 'code' => $code, 'state' => $state);
}
/**
* 刷新访问token
* @return mixed
*/
public function refreshAccessToken() {
$code = isset($_GET['code']) ? $_GET['code'] : '';
$state = isset($_GET['state']) ? $_GET['state'] : '';
$cache = $this->cache('auth_refresh_token');
if ($cache) {
$this->_refresh_token = $cache;
}
$res = $this->request(self::API_URL_PREFIX.'/oauth2/refresh_token', array(
self::APP_ID => $this->_APPID,
'refresh_token' => $this->_refresh_token,
'grant_type' => 'refresh_token',
), self::GET);
if ($res) {
$this->cache('auth_access_token', $res['access_token']);
$this->cache('auth_refresh_token', $res['refresh_token']);
$this->cache('auth_openid', $res['openid']);
}
return array('access_token' => $res['access_token'], 'code' => $code, 'state' => $state);
}
/**
* 获取用户信息
* @param bool $refresh 是否强制刷新
* @return bool|mixed
*/
public function getUserInfo($refresh = false) {
$this->_access_token = $this->getAuthAccessToken($refresh);
$cache = $this->cache('auth_openid');
if ($cache) {
$this->_openid = $cache;
}
$res = $this->request(self::API_URL_PREFIX.'/userinfo', array(
'access_token' => $this->_access_token,
'openid' => $this->_openid,
), self::GET);
if ($res) {
return $res;
}
return false;
}
/**
* 获取用户授权地址
* @param array $options
* @return string
*/
public function getLoginUrl($options = array()) {
$_options = array(
self::APP_ID => $this->_APPID,
'redirect_uri' => self::getCurrentUrl(),
'response_type' => 'code',
'scope' => 'snsapi_base', //snsapi_base | snsapi_userinfo
'state' => 'STATE',
);
$params = array_merge($_options, $options);
return 'https://open.weixin.qq.com/connect/oauth2/authorize?'.http_build_query($params).'#wechat_redirects';
}
/**
* 缓存接口Session实现
* @param $key 缓存索引key
* @param null $value 缓存值
* @return bool|mixed
*/
public function cache($key, $value = null) {
if (!session_id()) {
session_start();
}
if (empty($value)) {
if (isset($_SESSION[$key])) {
return $_SESSION[$key];
}
return false;
}
$_SESSION[$key] = $value;
return false;
}
}