• PHP:通过MVC,实现第三方登录(百度)


      这里,仓鼠将手把手记录下来实现第三方登录的流程,这里以百度为例

      

      百度开发者中心-官方网址:传送门

      所有第三方接口都不支持本地调试,只有真实的项目和服务器才有可能申请成功。
      所以申请的资料全部都要填写真实的项目信息。

    1、先注册一个百度开发者账号。
    2、然后进入应用管理中心,新建一个工程。






    3、然后再设置工程相关的配置参数。





    到这里,百度的第三方登录接口已经算是申请成功得了。下面我们就来学习如何运用PHP(基于ThinkMIMI的代码),实现第三方登录的功能。

    到这一步我们先来看看百度官方的接口文档:传送门


    里面提到了我们需要引导用户跳转到一个百度的URL(通过一个a标签进行跳转),这个URL里带有一个回调(也就是用户授权后,要跳转的地址)的URL地址,用户在百度中登录完成后,会自动跳转回该回调地址中,并带上一个CODE参数(形式:回调地址?code参数值),
    我们拿到这个CODE参数后再去获取百度的Access_Token,最后再用这个Access_Token去获得用户的相关信息。

    实践:

    1、我们现在C层创建一个方法,方法里面放入引导用户去授权的URL:

    例如:我有个ThirdParty的控制器,里面专门做第三方登录的

    namespace appadmincontroller;                 // 本类的文件位置
    use mimiController;                            // 调用controller类
    use mimiDb;                                    // 调用Db类
    use appadminmodelThirdParty as Third;
    use appadminmodelSite;
    use mimiextendRequest;
    use mimiextendSession;
    
    class ThirdParty extends Controller {
         /**
         * 引导用户去第三方百度进行登录授权
       */
       public function baidu() {
           header("location:https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=你自己的API_KEY&redirect_uri=你想回调的地址&display=popup");
        }

    2、V层只要做一个a标签,href跳转到上面的C层方法中就可以

    <?php
    $baiduLoginUrl   = ROOT_PATH.'index.php/admin/ThirdParty/baidu';               // 第三方登录页面
    ?>
    
    <a href="<?php echo $baiduLoginUrl; ?>" style="color: #ea5413; font-size: 15px;"> 百度登录</a>

    效果:

    当登录并授权后,将会跳回到你输入的回调地址:

    这里例如回调地址为:https://ljjpm.com/index.php/admin/ThirdParty/getBaidu

    那么,我们就需要在回调地址中输入内容:

    C层的getBaidu():

      /*
       * 获取access_token,进行登录注册处理
       */
       public function getBaidu() {
            $code          = Request::get('code');
            # 这个链接地址必须是当前回调链接地址,并且不带?参数。
            $redirect_uri  = 'https://ljjpm.com/index.php/admin/ThirdParty/getBaidu';
            $client_secret = "你的secret_key值";
            $client_id     = "你的api_key值";
            $url           = "https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code=$code&client_id=$client_id&client_secret=$client_secret&redirect_uri=$redirect_uri";
            # 发送CURL,获得Access_Token
            $res           = Request::https_request($url);
            $data          = json_decode($res, true);
            if (empty($data['access_token'])) {
                $this->error('百度授权异常!', '/');
            }
    
            # 发送CURL,获得百度用户的信息
            $url  = 'https://openapi.baidu.com/rest/2.0/passport/users/getInfo?access_token='.$data['access_token'];
            $res  = Request::https_request($url);
            $data = json_decode($res, true);
    
            if (empty($data['username'])) {
                $this->error('百度用户信息获取失败!', '/');
            } else {
                # 一般情况下呢,第三方回调都会有个userid,这是你用来区别下一次登录时,这个账号是否有注册过,如果没有则重新注册并直接登录。
                $userid = $data['userid'];
                $name   = $data['username'];
                
                # 查询数据库,看是否有注册过
                $info   = Db::name('user')->where(['id' => ['=', $userid]])->find();
    
                # 存在,直接登录
                if ($info) {
               # 将数据放在session中
                      Session::set('loginData', $info);
                       Site::redirect('登录成功', 'https://ljjpm.com/index.php/admin/home/index');
               exit;
                } else {
                # 不存在,注册再直接登录
                    # 先用昵称查询看看有没有被注册,被注册的话,则使用userid做用户名
                    $res  = Db::name('user')->field('id')->where(['username' => ['=', $name]])->find();
    
                    if ($res) {
                        $name = $userid;
                    }
                    $time = time();
                    $data = [
                    'id'        => $userid,
                        'username'  => $name,
                    ];
                    $id = Db::name('user')->data($data)->insert();
                    if ($id) {
                        $data['u_id'] = $id;
                    Session::set('loginData', $data);
                    Site::redirect('登录成功', 'https://ljjpm.com/index.php/admin/home/index');
                    exit;
                    }
                    $this->error('注册失败!', '/');
                }
            }
       }

    上面所提到的Request::https_request()代码为:

    /*
        * 接口数据传输的万能函数
        */
        public static function https_request($url, $data = null){
            # 初始化一个cURL会话
            $curl = curl_init();  
            //设置请求选项, 包括具体的url
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);  //禁用后cURL将终止从服务端进行验证
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            if (!empty($data)){
                curl_setopt($curl, CURLOPT_POST, 1);  //设置为post请求类型
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);  //设置具体的post数据
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);        
            $response = curl_exec($curl);  //执行一个cURL会话并且获取相关回复
            curl_close($curl);  //释放cURL句柄,关闭一个cURL会话
            return $response;
        }

    以上就是整个第三方登录的过程啦

    注意:

    因为我们是通过百度来获取用户信息的,所以用户的密码肯定是拿不到得啦,这时候我们拿到的基本上是用户的userid和用户名,

    那么我们的数据库上就存有id和用户名就好啦,下次再判断的时候,直接查询数据库的id即可,因为一个用户只有一个单独的userid返回

    END

  • 相关阅读:
    EF框架 处理decimal字段 Sum() 遇到NULL时的特殊处理
    RSA加密解密及RSA签名和验证
    SQL 类似switch的东东用法
    js抛物线动画
    MyBatis的结果映射(resultMap)
    mybatis中#和$符号的区别
    MyBatis 中Mapper.xml中注意事项
    MyBatis sql映射器 Mapper
    MyBatis的自定义别名和内置别名
    MyBatis简单认识(入门)
  • 原文地址:https://www.cnblogs.com/finalanddistance/p/10431535.html
Copyright © 2020-2023  润新知