微信網頁授權
首先創建微信的第三方類庫 項目是tp5 所以我就放在了\extend\Oauth\wxlogin\WXlogin.php;
<?php
namespace Oauth\wxlogin;
use think\Session;
/**
* 微信登錄
*/
class WXlogin
{
public function __construct()
{
$this->appID = 'wx0000090'; //微信appid
$this->callBackUrl = 'http://' . $_SERVER['HTTP_HOST'] . '/member/member/wxBack';//回調地址
$this->appSecret = 'ca6a577393a';//密鑰
}
/**
* 獲取微信url
* @return [type] [description]
*/
public function wxIndexUrl()
{
//--微信登錄-----生成唯一隨機串防CSRF攻擊
$state = md5(uniqid(rand(), true));
Session::set('wx_state', $state); //存到SESSION
$callback = urlencode($this->callBackUrl);
//'https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect';
$wxurl = "https://open.weixin.qq.com/connect/qrconnect?appid="
. $this->appID . "&redirect_uri="
. $callback . "&response_type=code&scope=snsapi_login&state="
. $state . "#wechat_redirect";
return $wxurl;die;
// header("Location: $wxurl");
}
/**
* 獲取微信返回信息
* @return [type] [description]
*/
public function wxGetUserInfo(){
if ($_GET['state'] != Session::get('wx_state')) {
return ['status'=>-1,'msg'=>'請求失敗'];
}
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $this->appID . '&secret=' . $this->appSecret . '&code=' . $_GET['code'] . '&grant_type=authorization_code';
$arr = Tcurl($url);
$arr = json_decode($arr,true);
//得到 access_token 與 openid
$url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $arr['access_token'] . '&openid=' . $arr['openid'] . '&lang=zh_CN';
$user_info = Tcurl($url);
$user_info = json_decode($user_info,true);
return ['status'=>1,'msg'=>'成功','data'=>$user_info];
}
}
然後在控制器中調用 返回微信登錄的url && 處理用戶的信息
/**
* 獲取微信登錄url
* @return [type] [description]
*/
public function wxloginUrl()
{
$Weixin = new \Oauth\wxlogin\WXlogin;
$wxurl = $Weixin->wxIndexUrl();
return $wxurl;
}
/**
* 微信回調接收用戶信息 && 處理登錄 && 註冊
* @return [type] [description]
*/
public function wxBack()
{
$Weixin = new \Oauth\wxlogin\WXlogin;
$wxData = $Weixin->wxGetUserInfo();
if ($wxData['status'] != 1) {jsonEncode('數據有誤');}
//進行項目邏輯處理開始
//結束
}
使用qq登錄
首先創建qq需要的類庫
tp5中 我放在了\extend\Oauth\qqlogin中;裏面有兩個文件,類庫QQconnent.php和調用類庫的Qqlogin.php
QQconnect.php內容 主要調用在Qqlogin.php中
<?php
namespace Oauth\qqlogin;
/**
* qq登錄授權
*/
class QQconnect
{
private $err = [
0 => '成功',
100000 => '缺少參數response_type或response_type非法',
100001 => '缺少參數client_id',
100002 => '缺少參數client_secret',
100003 => 'http head中缺少Authorization',
100004 => '缺少參數grant_type或grant_type非法',
100005 => '缺少參數code',
100006 => '缺少refresh token',
100007 => '缺少access token',
100008 => '該appid不存在',
100009 => 'client_secret(即appkey)非法',
100010 => '回調地址不合法,常見原因請見:回調地址常見問題及修改方法',
100011 => 'APP不處於上線狀態',
100012 => 'HTTP請求非post方式',
100013 => 'access token非法',
100014 => 'access token過期。 token過期時間爲3個月。如果存儲的access token過期,請重新走登錄流程,根據使用Authorization_Code獲取Access_Token或使用Implicit_Grant方式獲取Access_Token獲取新的access token值',
100015 => 'access token廢除。 token被回收,或者被用戶刪除。請重新走登錄流程,根據使用Authorization_Code獲取Access_Token或使用Implicit_Grant方式獲取Access_Token獲取新的access token值',
100016 => 'access token驗證失敗',
100017 => '獲取appid失敗',
100018 => '獲取code值失敗',
100019 => '用code換取access token值失敗',
100020 => 'code被重複使用',
100021 => '獲取access token值失敗',
100022 => '獲取refresh token值失敗',
100023 => '獲取app具有的權限列表失敗',
100024 => '獲取某OpenID對某appid的權限列表失敗',
100025 => '獲取全量api信息、全量分組信息',
100026 => '設置用戶對某app授權api列表失敗',
100027 => '設置用戶對某app授權時間失敗',
100028 => '缺少參數which',
100029 => '錯誤的http請求',
100030 => '用戶沒有對該api進行授權,或用戶在騰訊側刪除了該api的權限。請用戶重新走登錄、授權流程,對該api進行授權',
100031 => '第三方應用沒有對該api操作的權限。請發送郵件進行OpenAPI權限申請',
100032 => '過載,一開始未細分時可以用',
100033 => '缺少UIN參數',
100034 => '缺少skey參數',
100035 => '用戶未登陸',
100036 => 'RefreshToken失效',
100037 => 'RefreshToken已過期',
100038 => 'RefreshToken已廢除',
100039 => 'RefreshToken到達調用上限',
100040 => 'RefreshToken的AppKey非法',
100041 => 'RefreshToken的AppID非法',
100042 => 'RefreshToken非法',
100043 => 'APP處於暫停狀態',
100044 => 'Md5校驗失敗',
100045 => '用戶改密token失效',
100046 => 'g_tk校驗失敗',
100048 => '沒有設置companyID',
100049 => 'APPID沒有權限(get_unionid)',
100050 => 'OPENID解密失敗,一般是openid和appid不匹配',
100051 => '調試模式無權限',
];
#接口地址
private $LINK = [
'oauth' => 'https://graph.qq.com/oauth2.0/authorize', #獲取Authorization Code
'getAccessToken' => 'https://graph.qq.com/oauth2.0/token', #獲取或刷新Access Token
'getOpenid' => 'https://graph.qq.com/oauth2.0/me', #access_token
'getUserInfo' => 'https://graph.qq.com/user/get_user_info', #獲取用戶基本信息
];
#appid
private $appid;
#appkey
private $appkey;
#請求用戶授權時向用戶顯示的可進行授權的列表get_user_info,list_album...逗號分開,默認get_user_info
private $scope;
#回調地址(務必於應用上填寫的一致)
private $redirect_uri;
#錯誤代碼
private $errcode;
#錯誤信息
private $errmsg;
#單例
private static $_instance;
public function __construct()
{
$this->appid = '10789456';//申請的appid (qq互聯)
$this->appkey = 'd6ee34aa24df27';//申請的appkey
$this->redirect_uri = request()->domain() . '/member/member/qqaction';
}
public static function main()
{
if (!isset(self::$_instance)) {
if (func_num_args() < 2) {
exit('實例化-參數個數錯誤!');
}
$args = func_get_args();
self::$_instance = new self($args[0], $args[1]);
}
return self::$_instance;
}
/**
*獲取錯誤信息代碼
*
* @param string|array $flag 1:錯誤代碼,2:錯誤信息,others:數組
* @return string|array
*/
public function getError($flag = 0)
{
switch ($flag) {
case 0:$errmsg = $this->errmsg;
break;
case 1:$errmsg = $this->errcode;
break;
default:$errmsg = [
'errcode' => $this->errcode,
'errmsg' => $this->errmsg,
];
break;
}
return $errmsg;
}
#設置回調地址
public function setRedirectUri($uri)
{
$this->redirect_uri = $uri;
}
#獲取回調地址
public function getRedirectUri()
{
return $this->redirect_uri;
}
/**
*setScope 設置授權列表
*
* @param string|array $scope 授權列表,逗號分隔
* @return void
*/
public function setScope($scope)
{
if (is_array($scope)) {
$scope = implode(',', $scope);
}
$this->scope = $scope;
}
#獲取授權列表 true 數組,默認false 逗號分隔字符串
public function getScope($flag = false)
{
if ($flag) {
return explode(',', $this->scope);
}
return $this->scope;
}
/**
*getOauthUrl 獲取授權地址
*/
public function getOauthUrl($state = null, $display = null)
{
$keysArr = [
'response_type' => 'code',
'client_id' => $this->appid,
'state' => $state,
'redirect_uri' => urlencode($this->redirect_uri),
'display' => $display,
'scope' => $this->scope,
];
return self::combineURL($this->LINK['oauth'], $keysArr);
}
/**
*getAccessToken 通過code獲取access_token
*
* @param string $code 授權獲取的code
* @return string
*/
public function getAccessToken($code)
{
$keysArr = [
'grant_type' => 'authorization_code',
'client_id' => $this->appid,
'client_secret' => $this->appkey,
'redirect_uri' => urlencode($this->redirect_uri),
'code' => $code,
];
$link = self::combineURL($this->LINK['getAccessToken'], $keysArr);
$resData = self::qqCurl($link);
//--------檢測錯誤是否發生
if (strpos($resData, "callback") !== false) {
$lpos = strpos($resData, "(");
$rpos = strrpos($resData, ")");
$resData = substr($resData, $lpos + 1, $rpos - $lpos - 1);
$resData = json_decode($resData, true);
if (isset($resData['error'])) {
$this->errcode = $resData['error'];
$this->errmsg = $this->err[$resData['error']];
return false;
}
} else {
parse_str($resData, $param);
return $param['access_token'];
}
}
/**
*getUserOpenid 通過access_token獲取用戶openid
*
* @param string $access_token
* @return string
*/
public function getUserOpenid($access_token)
{
$link = self::combineURL($this->LINK['getOpenid'], ['access_token' => $access_token]);
$response = self::qqCurl($link);
//--------檢測錯誤是否發生
if (strpos($response, "callback") !== false) {
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos - 1);
}
$user = json_decode($response, true);
if (isset($user['error'])) {
$this->errcode = $user['code'];
$this->errmsg = $this->err[$user['code']];
return false;
}
return $user['openid'];
}
/**
*getUserInfo 獲取用戶基本信息
*
* @param string $access_token
* @param string $openid
* @return boolean|array
*/
public function getUserInfo($access_token, $openid)
{
$link = self::combineURL($this->LINK['getUserInfo'], [
'access_token' => $access_token,
'oauth_consumer_key' => $this->appid,
'openid' => $openid,
]);
$resData = self::qqCurl($link);
return self::checkResult($resData);
}
/**
*checkResult 請求結果處理
*
* @param string $resData 待檢測數據
* @return boolean|array
*/
public function checkResult($resData)
{
$resData = json_decode($resData, true);
if (!$resData || $resData['ret'] != 0) {
$this->errcode = $resData['ret'];
$this->errmsg = $resData['msg'];
return false;
} else {
return $resData;
}
}
/**
* combineURL 拼接url
* @param string $baseURL 基於的url
* @param array $keysArr 參數列表數組
* @return string 返回拼接的url
*/
public static function combineURL($baseURL, $keysArr)
{
$combined = $baseURL . "?";
$valueArr = array();
foreach ($keysArr as $key => $val) {
$valueArr[] = "$key=$val";
}
$keyStr = implode("&", $valueArr);
$combined .= ($keyStr);
return $combined;
}
/**
* curl請求
*/
public function qqCurl($url, $type = "GET", $data = '')
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
$type = strtolower($type);
switch ($type) {
case 'get':
break;
case 'post':
//post請求配置
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
break;
}
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
Qqlogin.php內容
<?php
namespace Oauth\qqlogin;
use Oauth\qqlogin\QQconnect;
use think\Session;
/**
* qq登錄授權
*/
class Qqlogin
{
public function qqloginUrl()
{
$QQconnect = new \Oauth\qqlogin\QQconnect();
$state = md5(uniqid(rand(), TRUE));
Session::set('state',$state);
return $QQconnect->getOauthUrl($state);
}
public function getUserInfo()
{
$code = $_GET['code'];
$state = $_GET['state'];
if ($state != Session::get('state')) {
return ['status'=>-1,'msg'=>'登錄有誤,請重新登錄'];
}
$QQconnect = new \Oauth\qqlogin\QQconnect();
#獲取access_token
$access_token = $QQconnect->getAccessToken($code);
if (!$access_token) {
return ['status' => -1, 'msg' => $QQconnect->getError()];
}
#獲取openid
$openid = $QQconnect->getUserOpenid($access_token);
if (!$openid) {
return ['status' => -1, 'msg' => $QQconnect->getError()];
}
#獲取用戶基本信息
$userinfo = $QQconnect->getUserInfo($access_token, $openid);
if (!$userinfo) {
return ['status' => -1, 'msg' => $QQconnect->getError()];
}
$result = array_merge($userinfo, ['openid' => $openid]);
return ['status' => 1, 'msg' => '成功', 'data' => $result];
}
}
然後在控制器中調用
/**
* qq登錄url
* @return [type] [description]
*/
public function qqloginUrl()
{
$Qqconnect = new \Oauth\qqlogin\Qqlogin();
$qqloginUrl = $Qqconnect->qqloginUrl();
return $qqloginUrl;
}
//qq回調
public function qqaction()
{
$Qqconnect = new \Oauth\qqlogin\Qqlogin();
$profile = $Qqconnect->getUserInfo();
if ($profile['status'] != 1) {jsonEncode('數據有誤');}
//邏輯處理
}