1. 程式人生 > >網站使用微信網頁授權,qq登入

網站使用微信網頁授權,qq登入

微信網頁授權

首先建立微信的第三方類庫 專案是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('資料有誤');}
        
        //邏輯處理
    }