资讯专栏INFORMATION COLUMN

全面解析Yii2跨域的SSO登录逻辑

daryl / 3377人阅读

摘要:简述本文章是我对如何实现登录做一个全面的逻辑解析。提醒注意在第步骤中,动态获取无的域名,此步骤必须做域名的判断处理,比如等这些可能出现的域名,以保证域名都能使用实现登录退出的机制。

简述

本文章是我对Yii2如何实现SSO登录做一个全面的逻辑解析。事实上,在此之前我也写过两篇文章关于SSO登录的实现方式以及进一步优化,包括这篇文章也都是介绍Yii2的SSO登录,逐步优化不断总结与分享,目的就是要把Yii2的SSO登录功能尽可能的做到极致,从程序开发的灵活性角度去思考问题,把一切潜在的局限扼杀在摇篮中。

实现步骤

1、在commonconfigmain.php文件配置如下:

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

2、新建一个login模块,然后打开commonconfigootstrap.php加下这么一段代码:

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

3、在loginconfigmain.php里修改 urlManager,改成下面这样子:

        "urlManager" => [
            "class" => "commoncomponentsMutilpleDomainUrlManager",
            "domains" => [
                "crm" => "//" . DOMAIN_CRM,
                "admin" => "//" . DOMAIN_ADMIN,
                "hr" => "//" . DOMAIN_HR,
                "oa" => "//" . DOMAIN_OA,
                "frontend" => "//" . DOMAIN_FRONTEND,
                "backend" => "//" . DOMAIN_BACKEND,
            //     "img" => "//" . DOMAIN_IMG,
                "api" => "//" . DOMAIN_API,
                "login" => "//" . DOMAIN_LOGIN,
            ],

            //"baseUrl" => "http://".DOMAIN_LOGIN."?redirectURL=http://".DOMAIN_HOME,
            "showScriptName" => false,
            "enablePrettyUrl" => true,  //美化URL
            "enableStrictParsing" => true, //设置有无‘s’;  
            // "suffix" => ".php",  
            "rules" => [ "" => "site/login",
                        // 如果没有这里,则访问域名不能直接打开默认Action (去除URL的“site/login”) 
            ]   
        ],

4、补充第3步骤缺少的MutilpleDomainUrlManager.php文件
MutilpleDomainUrlManager.php,这个文件按照我给你们的命名空间存放。

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。

5、修改login模块下的SiteController.php Login方法

    //登录
    public function actionLogin()
    {    
        //获取当前的URL
        $URL=Yii::$app->request->getHostInfo().Yii::$app->request->url;
        $URL1="http://".DOMAIN_CRM; 
        $redirectURL=Yii::$app->request->get("redirectURL"); 
        $redirectURL1="http://".DOMAIN_LOGIN; 

        $model = new LoginForm();
        TagDependency::invalidate(Yii::$app->cache, ["Session:".Yii::$app->session->id]);
 
        //验证是否已登录,非为登录
        if (!Yii::$app->user->isGuest) {  
           if(!empty($redirectURL)){
                $this->actionLogout();//强制性退出登录
               
                return $this->redirect($URL);

           }else{ 
                //redirectURL不存在时,提交表单判断
                if($this->siteLogin){     
                   if ($model->load(Yii::$app->request->post()) && $model->login()) { 
                       //判断该账号是否禁止登录 
                       if(empty($t_status=$model->user->attributes["t_status"]) && $t_status==0){ 
                           return $this->error($redirectURL1,[Yii::t("yii","The account is prohibited from logging in, please contact the administrator!")]);
                       }else{ 
                            if(empty($redirectURL)) return $this->redirect($URL1,301); 

                            return $this->redirect($redirectURL,301);
                        }          
                    } else { 
                        return $this->renderPartial("login", [
                            "model" => $model,
                        ]);
                    }
                }else{ 
                    return $this->goHome();
                }  
           }  
        } else {

            //redirectURL存在时,提交表单判断
            if ($model->load(Yii::$app->request->post()) && $model->login()) {     
                 //判断该账号是否禁止登录
                 if(empty($t_status=$model->user->attributes["t_status"]) && $t_status==0){ 
                    if(empty($redirectURL)){
                        return $this->error($redirectURL1,[Yii::t("yii","The account is prohibited from logging in, please contact the administrator!")]);
                    }
                    return $this->error($URL,[Yii::t("yii","The account is prohibited from logging in, please contact the administrator!")]);
                 }else{ 
                    if(empty($redirectURL)) return $this->redirect($URL1,301); 
               
                    return $this->redirect($redirectURL,301);
                 }        
            } else {   
                return $this->renderPartial("login", [
                    "model" => $model,
                ]);
            }
        }
    }

6、修改frontend模块下的SiteController.php Login方法

 public function actionLogin()
    {  
        //获取上一个URL
        $URL=Yii::$app->request->getHostInfo().Yii::$app->user->getReturnUrl();  
        if (!Yii::$app->user->isGuest) { 
            return $this->redirect("http://".DOMAIN_LOGIN."?redirectURL=".$URL);
        }
        $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=".$URL);
            }else{ 
                return $this->renderPartial("login", [
                                "model" => $model,
                            ]);
            }
        }
    }

7、在frontendviewsdefaultlayoutsmain.php的顶部加入下面代码

$redirectURL="http://".DOMAIN_LOGIN."?redirectURL=".Yii::$app->request->getHostInfo().Yii::$app->request->url;

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

注:在其它模块如:backend、crm等等当中仿造我这frontend的实现思路改改,即可实现整个项目的SSO登录机制。

提醒注意

1、在第1步骤中,动态获取无www的域名,此步骤必须做域名的判断处理,比如:www.xxx.com,www.xxx.com.cn,www.xxx.com:8099等这些可能出现的域名,以保证域名都能使用实现登录退出的机制。
2、在第5步骤和第7步骤中,使用Yii2自带的方法Yii::$app->request->getHostInfo().Yii::$app->request->url获取当前的url,是比较方便且高效的一种做法,能降低代码的冗余。
3、在第6步骤中的frontend模块下的SiteController.php Login方法里,用Yii2自带的方法Yii::$app->request->getHostInfo().Yii::$app->user->getReturnUrl()获取上一个url,这里必须特别注意是获取“上一个url”而不是当前的url,获取当前的url就变成了login.xxx.com了,这是不对的。

相关资料

Yii: 获取URL的一些方法:http://blog.csdn.net/iefreer/...

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

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

相关文章

  • 全面解析Yii2域的SSO登录逻辑

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

    2json 评论0 收藏0
  • 全面解析Yii2域的SSO登录逻辑

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

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

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

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

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

    DirtyMind 评论0 收藏0
  • 进一步优化Yii2域的SSO登录

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

    罗志环 评论0 收藏0

发表评论

0条评论

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