成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

網(wǎng)站接入qq,微信,微博第三方登陸(多網(wǎng)站,多級域名,多app端)

null1145 / 1194人閱讀

摘要:第三方登陸的整體思路是獲取第三方中的,然后與用戶關(guān)聯(lián)存到數(shù)據(jù)庫,進(jìn)行登陸。用于第三方應(yīng)用防止攻擊,成功授權(quán)后回調(diào)時會原樣帶回。

第三方登陸的整體思路是獲取第三方中的openid,然后與用戶關(guān)聯(lián)(存到數(shù)據(jù)庫),進(jìn)行登陸。

現(xiàn)在需求是:兩個(或多個)一級域名,如maxiye.cnyexima.com,同時每個域名下有多個二級域名分布,如:app.maxiye.cn,new.maxiye.cn,old.maxiye.cn,app.yexima.com,new.yexima.com,old.yexima.com...等,但是這些域名下使用了同一份代碼(對,就是馬甲),共享數(shù)據(jù)庫和session。同時旗下每個域名均可能包含pc,ios,Android端,如何全部接入第三方登陸?

qq,微信,微博接入要點(diǎn):
1.申請入口:QQ是QQ互聯(lián),微信是微信開放平臺,微博是微博開放平臺;
2.回調(diào)域設(shè)置QQ可以設(shè)置一級域名且可以有多個,必須http://開頭,;結(jié)束,如http://maxiye.cn;http://yexima.com;;微信只能設(shè)置到二級域名且只能一個,格式為:app.maxiye.cn;微博也可以設(shè)置一級域名且是一個:maxiye.cn;

注:由于QQ互聯(lián)開啟了回調(diào)地址強(qiáng)校驗(yàn),現(xiàn)在必須寫完整的回調(diào)路徑,多個以“;”分隔,如https://account.maxiye.cn/connect/callback/qq;https://account.yexima.com/connect/qc。(2018.3.26)

3.unionid獲取:多個app(同一開發(fā)者賬號下)共享數(shù)據(jù)庫,故需要使用unionid確認(rèn)身份。QQ獲取unionid需要額外申請權(quán)限,具體參考相同開發(fā)者賬號下的不同appid應(yīng)用如何打通;微信已有unionid獲取接口;微博中的uid即unionid;
4.本地也可以調(diào)試:比如要本地調(diào)試app.maxiye.cn的接入,只需要配置本地域名為local.maxiye.cnlocal可以改,但一級域名不能動,適用于QQ,微博;微信則必須是回調(diào)設(shè)置好的二級域名,可以先把回調(diào)地址設(shè)置為local.maxiye.cn,本地調(diào)試好了,再改),就可以正常接收第三方的回調(diào)了;

坑:
1.QQ接口返回的結(jié)果好多是jsonp格式,需要手動剝離callback();
2.微博獲取access_token竟然必須使用post,驚了;
3.微信不支持回調(diào)地址填寫一級域名,所以需要使用統(tǒng)一域名(代理)作為回調(diào)地址,然后內(nèi)部再重定向到發(fā)申請的域名;

下邊是一個寫好的工具類:

 [
            "qq" => [
                "app_id" => "100000000",
                "app_secret" => "f9038c3d07c*******7884edf3e31708",
            ],
            "weixin" => [
                "app_id" => "wxee7c90a7744c2002",
                "app_secret" => "13e649627894*******7a85a0e2f50e7",
            ],
            "weibo" => [
                "app_id" => "1200000000",
                "app_secret" => "e074de8*******d3818d0df9ca28c459",
            ],
        ],
        "yexima.com" => [
            "qq" => [
                "app_id" => "101111244",
                "app_secret" => "6ca59c6a1b1*******77e636a10ac334",
            ],
            "weixin" => [
                "app_id" => "wx0b822222ea9ee323",
                "app_secret" => "7f9cbd*******f37ce7b4c267bdde029",
            ],
            "weibo" => [
                "app_id" => "911111998",
                "app_secret" => "5b21c452f88e2982*******1722d8fcd",
            ],
        ],
    ];

    function __construct($params = [])
    {
        $this->type = $params["type"];
        $this->server = $_SERVER["SERVER_NAME"];
        foreach ($this->config as $k => $v) {
            if (stristr($this->server, $k) && isset($v[$this->type])) {
                $this->app_id = $v[$this->type]["app_id"];
                $this->app_secret = $v[$this->type]["app_secret"];
            }
        }
        if (isset($params["code"])) {
            $this->code = $params["code"];
        }
    }

    /**
     * 獲取用戶授權(quán)驗(yàn)證的鏈接
     * @return string
     */
    public function getOauthUrl()
    {
        $this->state = md5(uniqid(rand(), TRUE));
        Yii::$app->session->setFlash("oauth_state", $this->state);
        $redirect_uri = urlencode(Url::to(["login-by-openid", "type" => $this->type, true));
        if ($this->type == "weixin" && $this->server != $this->proxy) {//微信回調(diào)多域名代理處理
            $redirect_uri = str_replace($this->server, $this->proxy, $redirect_uri) . "%26redirect%3D" . $this->server;
        }
        $url = "";
        switch ($this->type) {
            case "qq"://qq回調(diào)域填寫一級域名并以“;”結(jié)束:http://maxiye.cn;http://yexima.com;
                $url = "https://graph.qq.com/oauth/show?which=Login&display=pc&response_type=code&client_id={$this->app_id}&state={$this->state}&display=web&redirect_uri={$redirect_uri}";
                break;
            case "weixin"://app.maxiye.cn不支持只填寫一級域名
                $url = "https://open.weixin.qq.com/connect/qrconnect?response_type=code&appid={$this->app_id}&state={$this->state}&scope=snsapi_login&redirect_uri={$redirect_uri}#wechat_redirect";
                break;
            case "weibo"://微博設(shè)置安全域名:maxiye.cn
                $url = "https://api.weibo.com/oauth2/authorize?response_type=code&client_id={$this->app_id}&state={$this->state}&display=web&redirect_uri={$redirect_uri}";
                break;

            default:

                break;
        }
        return $url;
    }

    /**
     * 獲取針對開發(fā)者賬號的惟一uuid
     * @return string unionid或uid
     */
    public function getUuid()
    {
        $openid = "";
        if ($this->type == "qq") {
            $this->getAccessToken();
        } else {
            $openid = $this->getOpenid();
        }
        $access_token = $this->access_token;
        $uuid = "";
        if ($access_token) {
            switch ($this->type) {
                case "qq":
                    $url = "https://graph.qq.com/oauth2.0/me?access_token={$access_token}&unionid=1";
                    // 返回示例...
                    /*callback({
                           "client_id":"YOUR_APPID",
                           "openid":"YOUR_OPENID",
                           "unionid":"YOUR_UNIONID"
                    });*/
                    $result = $this->get_contents($url);
                    if (strpos($result, "callback") !== false) {
                        $lpos = strpos($result, "(");
                        $rpos = strrpos($result, ")");
                        $result = json_decode(substr($result, $lpos + 1, $rpos - $lpos - 1), true);
                        $uuid = isset($result["unionid"]) ? $result["unionid"] : "";
                    }
                    return $uuid;
                    // return $openid;
                    break;
                case "weixin":
                    $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openid}";
                    // 返回示例
                    /*{
                        "openid":"OPENID",
                        "nickname":"NICKNAME",
                        "sex":1,
                        "province":"PROVINCE",
                        "city":"CITY",
                        "country":"COUNTRY",
                        "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
                        "privilege":[
                            "PRIVILEGE1",
                            "PRIVILEGE2"
                        ],
                        "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"

                    }*/
                    $result = json_decode($this->get_contents($url), true);
                    return isset($result["unionid"]) ? $result["unionid"] : "";
                    break;
                case "weibo":
                    return $openid;
                    break;

                default:

                    break;
            }
        }
        return $uuid;
    }

    /**
     * 獲取access_token
     * @param boolean $true false表示獲取原始結(jié)果,true獲取真正的access_token
     * @return string json包|string
     */
    public function getAccessToken($true = true)
    {
        //驗(yàn)證state
        if (Yii::$app->request->get("state", "") != Yii::$app->session->getFlash("oauth_state")) {
            return "";
        }
        $redirect_uri = urlencode(Url::to(["login-by-openid", "type" => $this->type], true));
        $url = "";
        switch ($this->type) {
            case "qq":
                $url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&code={$this->code}&client_id={$this->app_id}&client_secret={$this->app_secret}&redirect_uri={$redirect_uri}";
                //返回示例...
                //access_token=15C0CE01C0311240F9091A7DB6828E62&expires_in=7776000&refresh_token=7BFCE2E5B773D4F5531561A10E1C2B2D
                break;
            case "weixin":
                $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->app_id}&secret={$this->app_secret}&code={$this->code}&grant_type=authorization_code";
                //返回示例
                /*{
                "access_token":"ACCESS_TOKEN",
                "expires_in":7200,
                "refresh_token":"REFRESH_TOKEN",
                "openid":"OPENID",
                "scope":"SCOPE"
                }*/
                break;
            case "weibo":
                $url = "https://api.weibo.com/oauth2/access_token?client_id={$this->app_id}&client_secret={$this->app_secret}&grant_type=authorization_code&redirect_uri={$redirect_uri}&code={$this->code}";//新浪微博
                $post_data = [];
                return $this->post($url, $post_data);//撒幣制杖
                //返回示例
                /*{
                    "access_token": "SlAV32hkKG",
                    "remind_in": 3600,
                    "expires_in": 3600,
                    "uid":"12341234"
                }*/
                break;

            default:

                break;
        }
        if ($true) {
            $res_access_token = $this->get_contents($url);
            if ($this->type == "qq" && strpos($res_access_token, "access_token") !== false) {
                $token_result = ["access_token" => explode("=", explode("&", $res_access_token)[0])[1]];
            } else {
                $token_result = json_decode($res_access_token ?: "{}", true);
            }
            $access_token = !empty($token_result["access_token"]) ? $token_result["access_token"] : "";
            $this->access_token = $access_token;
            return $access_token;
        } else {
            return $this->get_contents($url);
        }
    }

    /**
     * post
     * post方式請求資源
     * @param string $url 基于的baseUrl
     * @param array $keysArr 請求的參數(shù)列表
     * @param int $flag 標(biāo)志位
     * @return string           返回的資源內(nèi)容
     */
    public function post($url, $keysArr, $flag = 0)
    {

        $ch = curl_init();
        if (!$flag) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $keysArr);
        curl_setopt($ch, CURLOPT_URL, $url);
        $ret = curl_exec($ch);

        curl_close($ch);
        return $ret;
    }

    /**
     * get_contents
     * 服務(wù)器通過get請求獲得內(nèi)容
     * @param string $url 請求的url,拼接后的
     * @return string           請求返回的內(nèi)容
     */
    public function get_contents($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_URL, $url);
        $response = curl_exec($ch);
        curl_close($ch);

        //-------請求為空
        if (empty($response)) {
            return "{}";
        }

        return $response;
    }

    /**
     * 獲取openid
     * @return string openid
     */
    public function getOpenid()
    {
        $res_access_token = $this->getAccessToken(false);
        if ($this->type == "qq" && strpos($res_access_token, "access_token") !== false) {
            $access_token = ["access_token" => explode("=", explode("&", $res_access_token)[0])[1]];
        } else {
            $access_token = json_decode($res_access_token ?: "{}", true);
        }
        $openid = "";
        if (isset($access_token["access_token"])) {
            $this->access_token = $access_token["access_token"];
            switch ($this->type) {
                case "qq":
                    $url = "https://graph.qq.com/oauth2.0/me?access_token={$access_token["access_token"]}";
                    // 返回示例...
                    // callback( {"client_id":"101406183","openid":"6C611CBE0C72F765572AE2472C9B59A4"} );
                    $result = $this->get_contents($url);
                    if (strpos($result, "callback") !== false) {
                        $lpos = strpos($result, "(");
                        $rpos = strrpos($result, ")");
                        $result = json_decode(substr($result, $lpos + 1, $rpos - $lpos - 1), true);
                        $openid = isset($result["openid"]) ? $result["openid"] : "";
                    }
                    break;
                case "weixin":
                    return $access_token["openid"];
                    break;
                case "weibo":
                    return $access_token["uid"];
                    /*$url = "https://api.weibo.com/oauth2/get_token_info?access_token={$access_token["access_token"]}";
                    //返回示例
                    {
                        "uid": 1073880650,
                        "appkey": 1352222456,
                        "scope": null,
                        "create_at": 1352267591,
                        "expire_in": 157679471
                    }
                    $result = $this->get_contents($url);
                    $openid = isset($result["uid"])?$result["uid"]:"";*/
                    break;

                default:

                    break;
            }
        }
        return $openid;
    }
}

使用方法如下:

//第三方登錄界面處理
public function actionLoginByOpenid(){
    Yii::$app->response->format= Response::FORMAT_HTML;
    $params = Yii::$app->request->get();
    $oauth = new OauthLogin($params);
    if(empty($params["code"])){
        $url = $oauth->getOauthUrl();
        return $this->redirect($url);
    }else{
        //微信代理跳轉(zhuǎn)處理
        if(isset($params["redirect"]) && $params["redirect"] != $oauth->server){
            $proxy = $oauth->proxy;
            $server = $params["redirect"];
            return $this->redirect(str_replace($proxy, $server, Url::current(["redirect"=>null], "http")));
        }
        $openid = $oauth->getUuid();
        if (!$openid) {
            //失敗處理TODO
        } else {
            //成功處理TODO
        }
        
    }
}

具體流程(qq為例)如下:
1.用戶點(diǎn)擊QQ登陸圖標(biāo),訪問鏈接http://app.maxiye.cn/site/login-by-openid?type=qq
2.服務(wù)器處理獲取QQ的授權(quán)鏈接,重定向到https://graph.qq.com/oauth/show?which=Login&display=pc&response_type=code&client_id=1**83&state=acc19**b&display=web&redirect_uri=http%3A%2F%2Fapp.maxiye.cn%2Fsite%2Flogin-by-openid%3Ftype%3Dqq;
3.用戶點(diǎn)擊QQ頭像或掃一掃授權(quán)通過,請求QQ服務(wù)器處理;
4.QQ在回調(diào)地址中添加code參數(shù)(Authorization Code),回調(diào)http://app.maxiye.cn/site/login-by-openid?type=qq&state=4a78***&code=1CA8DF***;
5.服務(wù)器驗(yàn)證state,根據(jù)code參數(shù)獲取access_token,然后獲取unionid(uid),處理結(jié)果。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/31983.html

相關(guān)文章

  • 關(guān)于網(wǎng)站微博QQ三方登陸

    摘要:近幾日由于公司業(yè)務(wù)需要,要做一個網(wǎng)站的第三方登陸,并且登陸之后并進(jìn)行驗(yàn)證,只有登陸過我們手機(jī)的第三方賬號才可以登陸網(wǎng)站。只能百度,發(fā)現(xiàn)騰訊對于網(wǎng)站登陸和手機(jī)登陸拿到的是不一樣的,如果要想一樣得寫申請信給,簡直就是蛋疼。 近幾日由于公司業(yè)務(wù)需要,要做一個網(wǎng)站的第三方登陸,并且登陸之后并進(jìn)行驗(yàn)證,只有登陸過我們手機(jī)app的第三方賬號才可以登陸網(wǎng)站。 這邊先說下oauth2.0大概的流程吧...

    mist14 評論0 收藏0
  • Yii2集成三方微博登錄(包含賬號申請、建表和常用業(yè)務(wù)邏輯全套流程)

    摘要:微博登錄是最常用的第三方賬號登錄之一。當(dāng)前狀態(tài)是未提交審核,待你開發(fā)完了上線后,提交微博審核,審核通過后即可正常使用。集成微博登錄首先簡介一下,第三方登錄開發(fā)的流程。文件是首頁,其實(shí)他的唯一作用就是產(chǎn)生一個微博登錄跳轉(zhuǎn)鏈接。 微博登錄是最常用的第三方賬號登錄之一。由于其網(wǎng)站用戶量大,可操作接口功能多,所以受到很多開發(fā)者的青睞。 既然是第三方,如果想使用它們的賬號進(jìn)行登錄,那么第一步就應(yīng)...

    EdwardUp 評論0 收藏0
  • Django使用Social-Auth實(shí)現(xiàn)微信三方網(wǎng)站掃碼登錄

    摘要:前言之前讓網(wǎng)頁公司制作新官網(wǎng)的時候規(guī)劃有第三方賬號的登錄功能,但由于當(dāng)時的一些開放平臺申請步驟比較繁瑣尤其是微信開放平臺,所以一直拖延著,到了最近只能自己添加相關(guān)的功能。 前言 之前讓網(wǎng)頁公司制作新官網(wǎng)的時候規(guī)劃有第三方賬號的登錄功能,但由于當(dāng)時的一些開放平臺申請步驟比較繁瑣(尤其是微信開放平臺),所以一直拖延著,到了最近只能自己添加相關(guān)的功能。 由于是剛接觸Python和Django...

    fox_soyoung 評論0 收藏0
  • 網(wǎng)站接入微信掃碼登錄并獲取用戶基本信息(微信開放平臺)

    摘要:現(xiàn)在的網(wǎng)站基本都接入微信登陸了,就好像下面這樣的。只需要用微信掃一下二維碼,這個網(wǎng)站就可以展示你的微信昵稱和頭像,免去注冊賬號和輸入密碼登錄的步驟,還免去設(shè)置頭像和昵稱的步驟,所以是挺方便的。 現(xiàn)在的網(wǎng)站基本都接入微信登陸了,就好像下面這樣的。 showImg(https://segmentfault.com/img/bVbc4jV?w=523&h=508); 只需要用微信掃一下二維碼...

    tangr206 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<