资讯专栏INFORMATION COLUMN

Restfual api 架构的第三方登录

shiyang6017 / 1291人阅读

摘要:需求分析用的架构实现第三方登录,如,微信登录等。好了,到这里架构的第三方登录已经实现了微博,淘宝等第三方登录实现的思路也如此,就是要对传入的参数进行改进一下就了。

序言

第三方登录的使用在当今非常普遍,不管是PC端还是手机端都很常见。因为它有着一号多用的特点,不管是在什么网站什么软件上只要有了这个第三方登录的功能就无需再次走注册步骤,直接用第三方的账号登录就可以了,方便吧?开发程序看重的是用户体验,为用户打造一款“麻雀虽小,五脏俱全”,使用便利的产品是我们的职责。那么话又说回来,在Restfual api 上如何实现第三方登录呢?我在Segmentfault上找不到我想要的答案,不过最终我也实现了,我把我的实现思路写出来,当然这只是我的一种实现方式,要是大家有更好的方法呢,乐意交流。

需求分析

1、用Restfual api的架构实现第三方登录,如QQ,微信登录等。

效果图

实现思路

1、建两个表,user表和user_login表。user表我就不详说了,这是基本表,我重点说一下user_login表。
user_login表字段:

id                    id
user_id               用户id
type                  登录类型(如:QQ,weixin)  
qq_access_token       QQ授权access_token
qq_openid             QQ openid
wx_access_token       微信授权access_token
wx_openid             微信openid

要是还有微博或者淘宝之类的其他第三方登录就如以上的规律加上对应的字段就行了。

2、gii生成UserLogin.php model如下:

 30],
            [["qq_access_token", "wx_access_token"], "string", "max" => 220],
            [["qq_openid", "wx_openid"], "string", "max" => 100]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            "id" => Yii::t("yii", "ID"),
            "user_id" => Yii::t("yii", "User ID"),
            "type" => Yii::t("yii", "Type"),
            "qq_access_token" => Yii::t("yii", "Qq Access Token"),
            "qq_openid" => Yii::t("yii", "Qq Openid"),
            "wx_access_token" => Yii::t("yii", "Wx Access Token"),
            "wx_openid" => Yii::t("yii", "Wx Openid"),
        ];
    }
     
}

3、控制器里的方法如下:
QQ登录

  public function actionQqLogin()
      { 
          $_model = new UserLogin();
          $model = new TUser();
          $post = Yii::$app->request->post();
          if(!empty($post))
          {
             $t_nickname = !empty($post["t_nickname"]) ? trim($post["t_nickname"]) : "";
             $access_token = !empty($post["access_token"]) ? trim($post["access_token"]) : "";
             $openid = !empty($post["openid"]) ? trim($post["openid"]) : "";
             $t_photo = !empty($post["t_photo"]) ? trim($post["t_photo"]) : "";//头像
             $res = UserLogin::find()
                      ->where(["type"=>"qq","qq_openid"=>$openid])
                      ->one();
            //判断是否已存在用户信息,存在则返回该条用户信息
             if(!empty($res))
             {
                 $res->qq_access_token = $access_token;
                 $res->save();
                //获取一条用户信息
                 $user = $model->getUserrow($res->user_id);
                 if(!empty($user)){

                    return $user;
                 }else{
                     ErrorMsg::Info(Yii::t("yii","Login fail"));
                 }               
             }else{ 
                  //保存新用户
                  $user = $this->saveUser($t_nickname,$t_nickname,$openid,"","",$t_photo);

                  if(empty($return["error_code"])){ 
                      $_model->user_id = $user->t_id;
                      $_model->type = "qq";
                      $_model->qq_access_token = $access_token;
                      $_model->qq_openid = $openid; 
                      $_model->save();
                      $user = $model->getUserrow($user->t_id); //保证返回数据字段一致
                  }

                  return $user;
              }
          }else{
              ErrorMsg::Info(Yii::t("yii","Login fail"));
          } 
      }

微信登录

 public function actionWxLogin()
      { 
          $_model = new UserLogin();
          $model = new TUser();
          $post = Yii::$app->request->post();
          if(!empty($post))
          {
             $t_nickname = !empty($post["t_nickname"]) ? trim($post["t_nickname"]) : "";
             $access_token = !empty($post["access_token"]) ? trim($post["access_token"]) : "";
             $openid = !empty($post["openid"]) ? trim($post["openid"]) : "";
             $t_photo = !empty($post["t_photo"]) ? trim($post["t_photo"]) : "";//头像
             $res = UserLogin::find()
                      ->where(["type"=>"weixin","wx_openid"=>$openid])
                      ->one(); 
            //判断是否已存在用户信息,存在则返回该条用户信息
             if(!empty($res))
             { 
                 $res->wx_access_token = $access_token;
                 $res->save();
                 //获取一条用户信息
                 $user = $model->getUserrow($res->user_id);
                 if(!empty($user)){

                    return $user;
                 }else{
                     ErrorMsg::Info(Yii::t("yii","Login fail"));
                 }               
             }else{
                   //保存新用户
                  $user = $this->saveUser($t_nickname,$t_nickname,$openid,"","",$t_photo);

                  if(empty($return["error_code"])){
                      $_model->user_id = $user->t_id;
                      $_model->type = "weixin";
                      $_model->wx_access_token = $access_token;
                      $_model->wx_openid = $openid;
                      $_model->save();
                      $user = $model->getUserrow($user->t_id);//保证返回数据字段一致
                  }
                  return $user;
              }
          }else{
              ErrorMsg::Info(Yii::t("yii","Login fail"));
          } 
      }

保存用户信息方法:

    public function saveUser($t_username,$t_nickname,$openid,$email,$phone,$t_photo)
    {          
        $access_token = sha1(time().$openid);
        $data = array(
          "t_nickname"=> $t_nickname,
          "t_password"=> base64_encode($openid),
          "t_state"   => 0,
          "t_photo"   => $t_photo?$t_photo:"/images/upload/100x100/no_photo.jpg",
          "t_timezone"=> "PRC",
          "t_language"=> "zh_cn",
          "access_token"=> $access_token,
          "rent_user_type"=>"3",
          "t_add_time"=>time(),
        );
        $model = new $this->modelUser;
        $model->attributes = $data;   

       if(!empty($t_nickname) && !empty($openid)){  
            if(!$model->save()){  
               ErrorMsg::Info(Yii::t("yii","Reg fail"));
            }  
           return $model;
        }else{ 
            ErrorMsg::Info(Yii::t("yii","m-log-2"));
        }
    }

第三方登录获取用户基本信息方法,TUser model里:

    public function getUserrow($uid)
     {    
          $user = $this->find()
                ->select(["access_token","t_password"])
                ->where(["t_id"=>$uid])
                ->one();
          if(!empty($user)){
              $result["access_token"]= !empty($access_token=$user->access_token)?$access_token:"";
              $result["appsercert"]  = !empty($t_password=$user->t_password)?$t_password:""; 
              
              return $result;  //返回给手机端用,只返回access_token和appsercert。
          }
     }

好了,到这里Restfual api 架构的第三方登录已经实现了,微博,淘宝等第三方登录实现的思路也如此,就是要对传入的参数进行改进一下就OK了。这是我实现Restfual api架构的第三方登录的思路,不足的提议,好的点赞哈,我们一起交流。

设想与问题

1、直接在user表里加上QQ、weixin的type,openid和access_token字段,这种做法拓展性不好,以后要是再增加如:微博,淘宝等第三方登录的话,又要操作user表,对user表操作过于频繁容易出问题,而且也不是每一个用户都会使用第三方登录,会造成大量空缺字段,浪费。我之所以独立创建user_login表也正是基于这些考虑的。
2、返回给手机端所有的用户信息。其实手机端不需要那些,你只要返回给手机端access_token和appsercert这两个字段就可以了,手机端会自己获取用户信息。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/59965.html

相关文章

  • Restfual api 架构三方登录

    摘要:需求分析用的架构实现第三方登录,如,微信登录等。好了,到这里架构的第三方登录已经实现了微博,淘宝等第三方登录实现的思路也如此,就是要对传入的参数进行改进一下就了。 序言 第三方登录的使用在当今非常普遍,不管是PC端还是手机端都很常见。因为它有着一号多用的特点,不管是在什么网站什么软件上只要有了这个第三方登录的功能就无需再次走注册步骤,直接用第三方的账号登录就可以了,方便吧?开发程序看重...

    cyqian 评论0 收藏0
  • Restfual api 架构三方登录

    摘要:需求分析用的架构实现第三方登录,如,微信登录等。好了,到这里架构的第三方登录已经实现了微博,淘宝等第三方登录实现的思路也如此,就是要对传入的参数进行改进一下就了。 序言 第三方登录的使用在当今非常普遍,不管是PC端还是手机端都很常见。因为它有着一号多用的特点,不管是在什么网站什么软件上只要有了这个第三方登录的功能就无需再次走注册步骤,直接用第三方的账号登录就可以了,方便吧?开发程序看重...

    Cheng_Gang 评论0 收藏0
  • Restfual api 架构三方登录

    摘要:需求分析用的架构实现第三方登录,如,微信登录等。好了,到这里架构的第三方登录已经实现了微博,淘宝等第三方登录实现的思路也如此,就是要对传入的参数进行改进一下就了。 序言 第三方登录的使用在当今非常普遍,不管是PC端还是手机端都很常见。因为它有着一号多用的特点,不管是在什么网站什么软件上只要有了这个第三方登录的功能就无需再次走注册步骤,直接用第三方的账号登录就可以了,方便吧?开发程序看重...

    Amio 评论0 收藏0
  • 堡垒跳板机实现——整体架构

    摘要:背景介绍最近,笔者接手公司的一项任务建造服务器的堡垒跳板机。关于跳板机的实现,其实简单版本网上一大堆,甚至更有开源堡垒机可供选择,方案很多。目标规模使用两台服务器做主从集群,所有实体服务器对接此集群,从而统一进行验证。 背景介绍 最近,笔者接手公司的一项任务:建造服务器的堡垒跳板机。 关于跳板机的实现,其实简单版本网上一大堆,甚至更有开源堡垒机Jumpserver可供选择,方案很多。接...

    JinB 评论0 收藏0
  • 让ERP服务更开放! ——用微服务架构搭建一套基于EBSAPI服务系统

    摘要:每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通通常是基于的。在微服务架构下,故障会被隔离在单个服务中。 1. 源码下载地址 源码链接: https://github.com/samt007/xy... 这是用Spring Cloud微服务架构搭建的一套基于EBS的API服务系统如对本文有任何的疑问,请联系我:samt007@qq.com 2. Introduc...

    JouyPub 评论0 收藏0

发表评论

0条评论

shiyang6017

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<