ホームページ  >  記事  >  バックエンド開発  >  Yii2 クロスドメイン SSO ログイン ロジックの包括的な分析

Yii2 クロスドメイン SSO ログイン ロジックの包括的な分析

WBOY
WBOYオリジナル
2016-06-20 12:26:231101ブラウズ

簡単な説明

この記事は、Yii2 が SSO ログインを実装する方法についての包括的な論理分析です。実は、以前に SSO ログインの実装とさらなる最適化について 2 つの記事を書きましたが、この記事でも Yii2 の SSO ログインを紹介し、段階的に最適化し、継続的に Yii2 の SSO ログインを改善することを目的としています。機能は可能な限り完璧である必要があり、プログラム開発の柔軟性の観点から問題を検討し、潜在的な制限をすべて取り除きます。

実装手順

1. commonconfigmain.php ファイルを次のように構成します。

<?php  use kartik\mpdf\Pdf;//动态获取无www的域名$host_array = explode('.', $_SERVER["HTTP_HOST"]); if (count($host_array) == 3) {         if(strpos($_SERVER["HTTP_HOST"],':')){  //判断域名是否存在端口号         $domain_array=explode(':', $host_array[2]);         define('DOMAIN', $host_array[1] . '.' . $domain_array[0]);//去掉端口号,避免域名带端口号无法退出     }else{        define('DOMAIN', $host_array[1] . '.' . $host_array[2]);     }  }//针对com.cn域名elseif (count($host_array) == 4) {       if(strpos($_SERVER["HTTP_HOST"],':')){         $domain_array=explode(':', $host_array[3]);         define('DOMAIN', $host_array[1] . '.' . $host_array[2]. '.' . $domain_array[0]);    }else{        define('DOMAIN', $host_array[1] . '.' . $host_array[2]. '.' . $host_array[3]);    }  }else{    //echo "本系统不支持本地访问,请配置域名";exit;}//将动态获取到的无www域名,配置上www、crm...define('DOMAIN_HOME', 'www.' . DOMAIN);define('DOMAIN_CRM', 'crm.' . DOMAIN);define('DOMAIN_HR', 'hr.' . DOMAIN);define('DOMAIN_WEIXIN', 'weixin.' . DOMAIN);define('DOMAIN_ADMIN', 'admin.' . DOMAIN);define('DOMAIN_OA', 'oa.' . DOMAIN);define('DOMAIN_FRONTEND', 'frontend.' . DOMAIN);define('DOMAIN_BACKEND', 'backend.' . DOMAIN);define('DOMAIN_API', 'api.' . DOMAIN);define('DOMAIN_LOGIN', 'login.' . DOMAIN);配置User 和 Session:'components' => [        'user' => [                        'identityClass' => 'login\models\User',            'enableAutoLogin' => true,            'identityCookie' => ['name' => '_identity', 'httpOnly' => true,'domain' => '.' . DOMAIN],            // 'returnUrl'=>'//' . DOMAIN_HOME,        ],                'session' => [                       'cookieParams' => ['domain' => '.' . DOMAIN, 'lifetime' => 0],                        'timeout' => 24*3600*30,        ],

2. 新しいログイン モジュールを作成し、commonconfigbootstrap.php を開き、これを追加します。コード部分:

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

3.loginconfigmain.php の urlManager を次のように変更します。

        'urlManager' => [            'class' => 'common\components\MutilpleDomainUrlManager',            '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 ファイルを追加します。ファイルは、指定した名前空間に従って保存されます。

<?phpnamespace common\components; use Yii; class MutilpleDomainUrlManager extends \yii\web\UrlManager{    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 \yii\base\InvalidConfigException('Please configure UrlManager of domain "' . $domain . '".');            }            $this->setBaseUrl($this->domains[$domain]);        }        $url = parent::createUrl($params);        $this->setBaseUrl($bak);        return $url;    }}

注: ドメイン URL を取得するために使用されます。 5. ログイン モジュール

    //登录    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,                ]);            }        }    }

の下にある SiteController.php Login メソッドを変更します。 6. フロントエンド モジュール

 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,                            ]);            }        }    }

の下にある SiteController.php Login メソッドを変更します。 7. Frontendviewsdefaultlayoutsmain.php 次のコードを追加します

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

8. 最後に、exit a タグに 9a9d8f96ab324c938fd4274b7542db6frequest->getHostInfo().Yii::$app->request- >url を使用します。 URL はより便利で効率的な方法であり、コードの冗長性を減らすことができます。

3. ステップ 6 のフロントエンド モジュールの SiteController.php Login メソッドで、Yii2 組み込みメソッド Yii::$app->request->getHostInfo().Yii:: $ を使用します。 app->user->getReturnUrl() は前の URL を取得します。現在の URL ではなく「前の URL」を取得することに特別な注意を払う必要があります。これは正しくありません。 。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。