资讯专栏INFORMATION COLUMN

关于Yii2如何实现跨域的SSO登录的解析

DirtyMind / 503人阅读

摘要:例如,淘宝登录的,登录成功的。所以思考如何实现这种跨域的登录就显得尤为重要了。需求分析进入登录页面的地址登录成功后跳转的地址下面我主要是以框架为例解说一下我是怎么实现这种跨越的登录的。

序言

近年来网络发展很快,参与网购的人越来越多,但是大家在网购的时候不知到有没有注意到无论是淘宝还是京东,他们用的都是二级域名,登录一个URL,登录成功后又是一个URL,作为一个开发者反正我是注意到了。

例如,淘宝登录的URL:https://login.taobao.com/memb...,登录成功的URL:https://www.taobao.com/?spm=a...。

或许大家可能觉得是多余,我一个URL就能搞定,为什么要整那么多个呢?麻烦。。。

大家可以想象一下,要是不把这两个模块分离的话,要是几千人,几万人,甚至上亿人同时登录的话,你就这么个服务器那不得崩了。所以思考如何实现这种跨域的SSO登录就显得尤为重要了。

需求分析

1、进入登录页面的URL地址:login.XXX.com
2、登录成功后跳转的URL地址:www.XXX.com
下面我主要是以Yii2框架为例解说一下我是怎么实现这种跨越的SSO登录的。

代码分析

结合需求,分布实施:

1、新建一个名为login的模块
把backend拷贝一份出来,改文件夹的名称为login,文件夹的名称改了大家可别忘了也把里边的文件的命名空间改一下,要不会找不到命名空间。对于多余的文件就把他删除了,省得占内存。至于删除啥保留啥的,就不详述了,因为这不是本文的重点,我这么跟你说吧,你需要用的就保留,不需要的通通删除。

2、写入配置信息
2.1、在commonconfig顶部加上domain信息,配置以下代码:

 $host_array = explode(".", $_SERVER["HTTP_HOST"]);
    if (count($host_array) == 3) {
        define("DOMAIN", $host_array[1] . "." . $host_array[2]);
    }
    //针对com.cn域名
    elseif (count($host_array) == 4) {
        define("DOMAIN", $host_array[1] . "." . $host_array[2]. "." . $host_array[3]);
    }else{
        //echo "本系统不支持本地访问,请配置域名";exit;
    }
    
    // echo "www." . DOMAIN;exit;
    define("DOMAIN_HOME", "www." . DOMAIN);
    
    // define("DOMAIN_API", "api." . DOMAIN);
    define("DOMAIN_LOGIN", "login." . DOMAIN);
    // define("DOMAIN_IMG", "img." . DOMAIN);

然后在components里配置User 和 Session:

"user" => [            
            "identityClass" => "loginmodelsUser",
            "enableAutoLogin" => true,
            "identityCookie" => ["name" => "_identity", "httpOnly" => true,"domain" => "." . DOMAIN],
            // "returnUrl"=>"//" . DOMAIN_HOME,
        ],        
"session" => [           
            "cookieParams" => ["domain" => "." . DOMAIN, "lifetime" => 0],            
            "timeout" => 3600,
        ],

以上配置完了之后,打开commonconfigbootstrap.php加下这么一段代码:

Yii::setAlias("login", dirname(dirname(__DIR__)) . "/login"); //增加自定义目录结构

2.2、在loginconfig里修改 urlManager,改成下面这样子:

"urlManager" => [
                "class" => "commoncomponentsMutilpleDomainUrlManager",
                "domains" => [
                    "backend" => "//" . DOMAIN_BACKEND,
                    // "mail" => "//" . DOMAIN_EMAIL,
                    // "img" => "//" . DOMAIN_IMG,
                    // "api" => "//" . DOMAIN_API,
                    "login" => "//" . DOMAIN_LOGIN,
                ],
                // "baseUrl" => "//" . DOMAIN_HOME,   # Default BaseUrl
                "showScriptName" => false,
                "enablePrettyUrl" => true,  //美化URL
                "enableStrictParsing" => true, //设置有无‘s’;  
                // "suffix" => ".php",  
                "rules" => [ "" => "site/login", // 如果没有这里,则访问域名不能直接打开默认Action (去除URL的“site/login”) 
                ]   
       ],

3、新建一个MutilpleDomainUrlManager.php文件
MutilpleDomainUrlManager.php,这个文件按照我给你们的命名空间存放。

  namespace commoncomponents;
     
    use Yii;
     
    class MutilpleDomainUrlManager extends yiiwebUrlManager
    {
        public $domains = array();
     
        public function createUrl($domain, $params = array()) {
            if (func_num_args() === 1) {
                $params = $domain;
                $domain = false;
            }
            $bak = $this->getBaseUrl();
            if ($domain) {
                if (!isset($this->domains[$domain])) {
                    throw new yiiaseInvalidConfigException("Please configure UrlManager of domain "" . $domain . "".");
                }
                $this->setBaseUrl($this->domains[$domain]);
            }
            $url = parent::createUrl($params);
            $this->setBaseUrl($bak);
            return $url;
        }
    }

附:这样我们可以使用以下代码生成其它domain url

Yii::$app->urlManager->createUrl("site/index"),   # www.xxx.com/site/index
Yii::$app->urlManager->createUrl("login", "site/login"),  #  login.xxx.com/site/login
Yii::$app->urlManager->createUrl("article/list"),  #  login.xxx.com/article/list
Yii::$app->urlManager->createUrl("man", "user/view"),  #  man.xxx.com/user/view

4、修改SiteController.php的Login方法
4.1、login模块

 logincontrollersSiteController.php

     public function actionLogin()
        {   
            $URL=Yii::$app->request->get("redirectURL");  
            $model = new LoginForm();
            //判断是否已登录,非为登陆
            if (!Yii::$app->user->isGuest) { 
                $this->actionLogout();//强制性退出
                return $this->redirect("http://".DOMAIN_LOGIN."?redirectURL=http://".DOMAIN_HOME);
            } 
        
            if ($model->load(Yii::$app->request->post()) && $model->login()) {
                if(empty($URL)){
                    return $this->redirect("http://".DOMAIN_HOME,301);
                }else{
                    return $this->redirect($URL,301);
                }           
                // return $this->goBack();
            } else { 
                return $this->renderPartial("login", [
                    "model" => $model,
                ]);
            }
        }
        

4.2、frontend模块

frontendcontrollersSiteController.php
      public function actionLogin()
    {   
        $URL=Yii::$app->request->get("redirectURL"); 
         //判断是否已登录,非为登陆
        if (!Yii::$app->user->isGuest) {
            // return $this->goHome();
            $this->actionLogout();//强制性退出
            return $this->redirect("http://".DOMAIN_LOGIN."?redirectURL=http://".DOMAIN_HOME);
        }
        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
             return $this->goBack();
             
        } else {
            if(empty($URL)){
                return $this->redirect("http://".DOMAIN_LOGIN."?redirectURL=http://".DOMAIN_HOME);
            }else{
                return $this->renderPartial("login", [
                                "model" => $model,
                            ]);
            }
            
        }
    }

5、视图渲染
5.1在frontendviewslayoutsmain.php的顶部加入红框的代码

5.2、最后在退出的a标签这么输出

OK,到这里就全部完成了,这时候大家可以测试一下,你会惊奇的发现Yii2跨域的SSO登录已经实现了。哈哈。。。

常见问题

1、手动输入login.XXX.com进入登录页面成功了,关闭浏览器后,再重新打开,地址栏输入www.XXX.com还是登录状态。

解决方式:
在login的方法里边的验证是否已登录调用“ $this->actionLogout()”退出方法,然后给他个重定向的URL,如:return $this->redirect("http://".DOMAIN_LOGIN."?redirectURL=http://".DOMAIN_ADMIN),这样就能防止你在地址栏输入login.XXX.com进入到登录页面了还退出不成功的问题。

     参考代码:
         //判断是否已登录,非为登陆
         if (!Yii::$app->user->isGuest) { 
                        $this->actionLogout();//强制性退出
                        return $this->redirect("http://".DOMAIN_LOGIN."?redirectURL=http://".DOMAIN_ADMIN);
                    } 

2、使用Yii::$app->urlManager->createUrl("login", "site/login")这种方式生成
domain url在视图无法生成的问题,原因是这种方式只能在控制器里面使用。

相关资料

Yii2 配置 跨域登录实例:http://www.kuitao8.com/201505...
Yii2 如何利用redirect让页面自动跳转到外站?:https://segmentfault.com/q/10...

全文完,如有不足或者更好的方式方法,欢迎大家踊跃提出,我们一起相互交流学习。

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

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

相关文章

  • 全面解析Yii2SSO登录逻辑

    摘要:简述本文章是我对如何实现登录做一个全面的逻辑解析。提醒注意在第步骤中,动态获取无的域名,此步骤必须做域名的判断处理,比如等这些可能出现的域名,以保证域名都能使用实现登录退出的机制。 简述 本文章是我对Yii2如何实现SSO登录做一个全面的逻辑解析。事实上,在此之前我也写过两篇文章关于SSO登录的实现方式以及进一步优化,包括这篇文章也都是介绍Yii2的SSO登录,逐步优化不断总结与分享,...

    daryl 评论0 收藏0
  • 全面解析Yii2SSO登录逻辑

    摘要:简述本文章是我对如何实现登录做一个全面的逻辑解析。提醒注意在第步骤中,动态获取无的域名,此步骤必须做域名的判断处理,比如等这些可能出现的域名,以保证域名都能使用实现登录退出的机制。 简述 本文章是我对Yii2如何实现SSO登录做一个全面的逻辑解析。事实上,在此之前我也写过两篇文章关于SSO登录的实现方式以及进一步优化,包括这篇文章也都是介绍Yii2的SSO登录,逐步优化不断总结与分享,...

    2json 评论0 收藏0
  • 全面解析Yii2SSO登录逻辑

    摘要:简述本文章是我对如何实现登录做一个全面的逻辑解析。提醒注意在第步骤中,动态获取无的域名,此步骤必须做域名的判断处理,比如等这些可能出现的域名,以保证域名都能使用实现登录退出的机制。 简述 本文章是我对Yii2如何实现SSO登录做一个全面的逻辑解析。事实上,在此之前我也写过两篇文章关于SSO登录的实现方式以及进一步优化,包括这篇文章也都是介绍Yii2的SSO登录,逐步优化不断总结与分享,...

    xingpingz 评论0 收藏0
  • 关于Yii2如何实现SSO登录解析

    摘要:例如,淘宝登录的,登录成功的。所以思考如何实现这种跨域的登录就显得尤为重要了。需求分析进入登录页面的地址登录成功后跳转的地址下面我主要是以框架为例解说一下我是怎么实现这种跨越的登录的。 序言 近年来网络发展很快,参与网购的人越来越多,但是大家在网购的时候不知到有没有注意到无论是淘宝还是京东,他们用的都是二级域名,登录一个URL,登录成功后又是一个URL,作为一个开发者反正我是注意到了。...

    Anchorer 评论0 收藏0
  • 进一步优化Yii2SSO登录

    摘要:序言本文主要是对关于如何实现跨域的登录的解析的改进,因为在那篇文章中我已经写出了登录的基本实现过程,现在是进一步优化。实现永久登录状态。只要不点击退出登录,就一直保持着登录状态。存在时,提交表单判断修改的过期时间,设置到极大值。 序言 本文主要是对关于Yii2如何实现跨域的SSO登录的解析的改进,因为在那篇文章中我已经写出了SSO登录的基本实现过程,现在是进一步优化。主要优化的部分有两...

    罗志环 评论0 收藏0

发表评论

0条评论

DirtyMind

|高级讲师

TA的文章

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