百搜论坛欢迎您的加入!
adimg adimg
 
昨日:篇  今日:篇   总帖:篇   会员:
博主最大Lv63   
ThinkPHP接入QQ互联实现登录的案例分析     
本篇介绍了使用ThinkPHP接入qq互联实现第三方登录的方法,作为一个小案例来为各位讲解,希望对各位有帮助。

ThinkPHP接入QQ互联实现登录的案例分析

我的一个二级域名项目想在也想接入QQ第三方登录功能,该项目采用的thinkphp5框架开发的项目,在网上搜了一些接入的案例,个人觉得鱼龙混杂不太适合自己,现在自己重新在thinkphp5框架上开发这个功能,下面是详细的开发步骤。

(推荐教程:thinkphp教程

第一步、下载QQ互联SDK,我们是基于thinkphp5框架下的,当然是要用PHP版的SDK,下载下来后的文件目录如下。

1.png

第二步、将SDK主要目录上传到服务器合适的目录下,先说下SDK的主要的目录是API文件夹里面的class目录,当初为了做配置设置项测试,我上传了install文件夹,然后再开发环境配置了APP ID、APP Key以及callback_url,配置好之后会在API/comm文件夹中多处一个inc.php配置文件,最后再recorder类中会引用这个配置文件。可是在后面的 开发过程中我发现会报这个错The state does not match. You may be a victim of CSRF。后面我把qqlogin方法里面的 state放到session中,对官网的DEMO SDK已经完全失去信心了,不在用QQ互联全部的文件而是挑几个重要的类文件来做开发。后面想想官方给的SDK只是普通的PHP代码格式,我应用到thinkphp那很多东西都已经变了,最后我选择上个类文件,QC.php、URL.php、Oauth.php上传到extend/qqlogin目录下。在thinkphp5的项目中扩展类一般上传到extend文件夹下,如下图所示我上次的目录位置。

2.png

第三步、改造上述三个类文件,因为QC.php是继承了Oauth.php,我们从后者改起,去掉require_once,加上命名空间如namespace qqlogin,首先看成员属性,类常量是腾讯平台的地址,不用管,原来有三个属性,recorder、error不需要,注释掉或直接删掉。下文同样,因为5个类文件我们只用到3个类文件,一个是报错类一个读取配置相关类。下面看Oauth.php成员属性、qqlogin跳转方法、qqcallback回调方法的,其他两个类文件没有太大的改大,按照上述规则改即可

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

<?php

/* PHP SDK

 * @version 2.0.0

 * @author connect@qq.com

 * @copyright © 2013, Tencent Corporation. All rights reserved.

 */

namespace qqlogin;

use qqlogin;

class Oauth{

    const VERSION = "2.0";

    const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";

    const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";

    const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";

    // protected $recorder;

    public $urlUtils;

    // protected $error;

     

    function __construct(){

        // $this->recorder = new Recorder();

        $this->urlUtils = new URL();

        // $this->error = new ErrorCase();

    }

    public function qq_login(){

        // $appid = $this->recorder->readInc("appid");

        // $callback = $this->recorder->readInc("callback");

        // $scope = $this->recorder->readInc("scope");

        $appid = $this->appid;

        $callback = $this->callback;

        $scope = $this->scope;

        //-------生成唯一随机串防CSRF攻击

        $state = md5(uniqid(rand(), TRUE));

        // $this->recorder->write('state',$state);

        session('state',$state);

        //-------构造请求参数列表

        $keysArr = array(

            "response_type" => "code",

            "client_id" => $appid,

            "redirect_uri" => $callback,

            "state" => $state,

            "scope" => $scope

        );

        $login_url =  $this->urlUtils->combineURL(self::GET_AUTH_CODE_URL, $keysArr);

        return $login_url;

    }

    public function qq_callback(){

        // $state = $this->recorder->read("state");

        //--------验证state防止CSRF攻击

        if(input('state') != session('state')){

            // $this->error->showError("30001");

            exit('30001');

        }

        //-------请求参数列表

        $keysArr = array(

            "grant_type" => "authorization_code",

            "client_id" => $this->appid,

            "redirect_uri" => urlencode($this->callback),

            "client_secret" => $this->appkey,

            "code" => $_GET['code']

        );

        //------构造请求access_token的url

        $token_url = $this->urlUtils->combineURL(self::GET_ACCESS_TOKEN_URL, $keysArr);

        $response = $this->urlUtils->get_contents($token_url);

        if(strpos($response, "callback") !== false){

            $lpos = strpos($response, "(");

            $rpos = strrpos($response, ")");

            $response  = substr($response, $lpos + 1, $rpos - $lpos -1);

            $msg = json_decode($response);

            // if(isset($msg->error)){

            //     $this->error->showError($msg->error, $msg->error_description);

            // }

        }

        $params = array();

        parse_str($response, $params);

        // $this->recorder->write("access_token", $params["access_token"]);

        // return $params["access_token"];

        session('access_token',$params["access_token"]);

    }

}

第四步、编写控制器调用函数和回调函数,同时检查回调地址是否正确(回调地址是当你添加QQ第三方登录QQ互联返回跳转的地址,该地址携带重要参数,能获取最后用户的数据),有些时候如果你在QQ互联填写的回调地址与你控制器的不一样,那么最后就会卡在那个QQ互联填写的回调地址那,如www.100txy.com/index.php?code=65B7668A4F1BBB71DD0DF52B55AC1FC1&state=804e921e18e3545ecdf690316639c067。下面是控制器方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

use qqlogin\QC;

// 处理qq登录

    public function qqlogin(){

        $qq = new QC();

        $url = $qq->qq_login();

        $this->redirect($url);

    }

    // qq登录回调函数

    public function qqcallback(){

        $qq = new QC();

        $qq->qq_callback();

        $qq->get_openid();

        $qq = new QC();

        $datas = $qq->get_user_info();

        die(var_dump($datas));//为用户数据

    }

值得注意的是在回调函数里面要实例化两次QC才能拿到用户信息,第二次实例化的时候才有openid和access_token两个参数。

更多Thinkphp教程,请关注PHP中文网

以上就是ThinkPHP接入QQ互联实现登录的案例分析的详细内容

 0  已被阅读了1131次  楼主 2020-06-23 13:15:41
回复列表

回复:ThinkPHP接入QQ互联实现登录的案例分析

联系站长 友链申请桂ICP备19000949号-1     桂ICP备19000949号-1
您的IP:3.140.198.173,2024-04-29 09:01:30,Processed in 0.02558 second(s).
免责声明: 本网不承担任何由内容提供商提供的信息所引起的争议和法律责任。
Powered by HadSky 7.12.9
已有0次打赏
(0) 分享
分享
取消
免责声明
1、本站资源,均来自网络,版权归原作者,所有资源和文章仅限用于学习和研究目的 。
2、不得用于商业或非法用途,否则,一切责任由该用户承担 !
如果觉得本文还不错请点个赞或者打赏点轻币哦~
拒绝伸手党,拿走请回复,尊重楼主,尊重你我他~

侵权删除请致信 E-Mail:207882320@qq.com