三方登录之QQ登录

2018-02-26 10:19:54 查看 1289 回复 0

如果网站没有一个三方登录,可以毫不留情的说这个网站很失败。会流失很多用户资源。
既然如此,那就记录一个qq登录的代码吧!
逻辑是:1.根据QQ互联得到QQ的openid。2.比对数据库判断用户。3.进行用户登录或者用户绑定。

控制器:auth

public function qqlogin(){
        $qqLogin = new QQLogin();
        $code = I('get.code','');
        if(empty($code)){
            $qqLogin->getCode();
        }
        $openId =  $qqLogin->getOpenId($code);
        if($openId===false){
            $this->err($qqLogin->getError());
        }
        if(empty($openId)){
            $this->err('OPEN ID IS EMPTY');
        }
        $user = new userModel();
        $res = $user->qqAutoLogin($openId);
        if($res === false){
            $this->err($user->getError());
        }else if($res === true){
            redirect(TRUE_DIR);
        }else{
           $qqinfo =  $qqLogin->getQQInfo($openId);
           if($qqinfo===false){
               $this->err($qqLogin->getError());
           }
           session('authinfo',$qqinfo);
           session('authtype','qq');
            session('authopenid',$openId);
           $this->redirect('index/bind');
        }

    }

模型:user

//QQ自动登录
    function qqAutoLogin($openid){
        $user = $this->table('auth_user')->where(array('openid'=>$openid))->find();
        if($user){
            $res = $this->table('user')->where(array('id'=>$user['create_by']))->find();
            if(!$res){
                $this->error = '用户异常,无法登录';
                return false;
            }
            if($res['status']==0){
                $this->error = '帐号无法登录,请联系管理员';
                return false;
            }
            self::login($res);
            return true;
        }else{
            return U('index/bind');
        }
    }

功能类:QQlogin

class QQLogin {
                    //应用的APPID
                    private $app_id = null;
                    //应用的APPKEY
                    private $app_secret = null;
                    //成功授权后的回调地址
                    private $my_url = null;

                    protected $error = null;

					public function __construct() {
                        $qqLoginConfig = C('QQ_LOGIN');
                        if(!$qqLoginConfig){
							//E('请配置QQ登录参数。');
                            $this->error='请配置QQ登录参数';
                            return false;
						}
						$this->app_id=$qqLoginConfig['APP_ID'];
                        $this->app_secret=$qqLoginConfig['APP_Key'];
                        //REDIRECT_URL
						$this->my_url=urlencode($qqLoginConfig['REDIRECT_URL']);
					}
					//获取code
					function getCode(){

                        //state参数用于防止CSRF攻击,成功授权后回调时会原样带回
                        $state = md5(uniqid(rand(), TRUE));
                        session('state',$state);
                        //拼接URL
                        $dialog_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id="
                            . $this->app_id . "&redirect_uri=" . $this->my_url. "&state="
                            .$state;
                        exit("<script> top.location.href='" . $dialog_url . "'</script>");
                    }
                    function getAccessToken($code){
//拼接URL

                        $token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&"
                            . "client_id=" . $this->app_id . "&redirect_uri=" . $this->my_url
                            . "&client_secret=" . $this->app_secret . "&code=" . $code;
                        $response = file_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))
                            {
                                //E($msg->error_description,$msg->error);
                                $this->error=$msg->error_description;
                                return false;
                                /* echo "<h3>error:</h3>" . $msg->error;
                                 echo "<h3>msg  :</h3>" . $msg->error_description;
                                 exit;*/
                            }
                        }
                        //Step3:使用Access Token来获取用户的OpenID
                        $params = array();
                        parse_str($response, $params);
                            $accessToken = $params['access_token'];
                            session('qqlogin_accesstoken',$accessToken);

                        return $accessToken;
                    }
                    function getOpenId($code){
                        if(I('param.state') == session('state'))
                        {

                            $access_token = self::getAccessToken($code);
                            if($access_token===false){
                                return false;
                            }

                            $graph_url = "https://graph.qq.com/oauth2.0/me?access_token=".$access_token;
                             $str  = file_get_contents($graph_url);
                             if (strpos($str, "callback") !== false)
                             {
                                 $lpos = strpos($str, "(");
                                 $rpos = strrpos($str, ")");
                                 $str  = substr($str, $lpos + 1, $rpos - $lpos -1);
                             }
                             $user = json_decode($str);
                             if (isset($user->error))
                             {
                                 //E($user->error_description,$user->error);
                                 $this->error=$user->error_description;
                                 return false;
                                /* echo "<h3>error:</h3>" . $user->error;
                                 echo "<h3>msg  :</h3>" . $user->error_description;
                                 exit;*/
                             }
                             return $user->openid;
                          }
                        else
                        {
                            //echo("The state does not match. You may be a victim of CSRF.");
                            //E('The state does not match. You may be a victim of CSRF.');
                            $this->error='The state does not match. You may be a victim of CSRF.';
                            return false;
                        }
                    }
                    function getQQInfo($openid){
                        $accesstoken = session('qqlogin_accesstoken');
                        $graph_url = "https://graph.qq.com/user/get_user_info?access_token=".$accesstoken."&oauth_consumer_key=".$this->app_id."&openid=".$openid;
                        $str  = file_get_contents($graph_url);
                        $user = json_decode($str);
                        if($user->ret!=0){
                            $this->error=$user->msg;
                            return false;
                        }else{
                            return $user;
                        }


                    }

                    function getError(){
                        return $this->error;
                    }

				}