萨姆耶/yii2-discourse-sso

一套用于Discourse独角兽的工具。

1.0 2017-12-13 09:07 UTC

This package is not auto-updated.

Last update: 2024-09-14 16:57:46 UTC


README

Discourse SSO for Yii2

目前这个扩展仅真正处理登录。

安装和配置相当简单。

请确保按照Discourse上的这个指南进行操作 遵循此指南,并在设置SSO后,获取所需的密钥,然后按照以下方式配置您的应用程序

    'discourseSso' => [
    	'class' => 'sammaye\discourse\Sso',
    	'secret' => "Some super secret, super awesome dupa secret key"
    ],

这就是安装此扩展的方式。现在您只需要学习如何使用它。

您的扩展可以通过 Yii::$app->discourseSso 访问。这是整个README中使用的位置。

第一步是在您的 SiteController.php 中设置一个操作,以实际执行登录逻辑

public function actionDiscourseSso()
{
	$request = Yii::$app->getRequest();
	$sso = Yii::$app->discourseSso;
	
	$payload = $request->get('sso');
	$sig = $request->get('sig');

	if(!($sso->validate($payload, $sig))){
		// invaild, deny
		throw new ForbiddenHttpException('Bad SSO request');
	}
	
	$nonce = $sso->getNonce($payload);
	
	if(Yii::$app->getUser()->isGuest){
		// We add session variable to track it after we log the user in so we can redirect them back
		// This method works well with custom login methods like social networks
		Yii::$app->getSession()->set('sso', ['sso' => $payload, 'sig' => $sig]);
		return $this->redirect(['site/login']);
	}else{
		$user = Yii::$app->getuser()->getIdentity();
	}
	
	Yii::$app->getSession()->remove('sso');
	
	// We send over the data
	$userparams = [
    	"nonce" => $nonce,
    	"external_id" => (String)$user->_id,
    	"email" => $user->email,
    	
    	// Optional - feel free to delete these two
    	"username" => $user->username,
    	"name" => $user->username,
    	
    	//'avatar_url' => Url::to(['image/profile-image', 'id' => (String)$user->_id], 'http')
	];
	$q = $sso->buildLoginString($userparams);
	
	/// We redirect back
	header('Location: ' . Yii::getAlias('@discourse') . '/session/sso_login?' . $q);
}

尽管这已经完成了90%,但它并没有完成。如果您注意的话

Yii::$app->getSession()->set('sso', ['sso' => $payload, 'sig' => $sig]);

我们将 sigpayload 加载到会话中,这样我们就可以知道是否来自单点登录,以便我们可以重定向回来。这意味着在我们的登录函数中(无论是 login() 还是某些社交登录),我们需要将其更改为(以 login 为例)

public function actionLogin()
{
    if (!\Yii::$app->user->isGuest) {
        return $this->goHome();
    }

    $model = new LoginForm();
    if ($model->load(Yii::$app->request->post()) && $model->login()) {
    	
    	if($sso = Yii::$app->getSession()->get('sso')){
    		return $this->redirect([
    			'discourse-sso', 
    			'sso' => $sso['sso'], 
    			'sig' => $sso['sig']
			]);
    	}
    	
    	if($model->getUser()->profile_filled){
        	return $this->goBack();
    	}else{
    		return $this->redirect(['user/about-me']);
    	}
    } else {
        return $this->render('login', [
            'model' => $model,
        ]);
    }
}

注意 if($sso = Yii::$app->getSession()->get('sso')){,这里就是魔法所在,它检测到我们的单点登录并重定向回我们的单点登录函数。

要自定义此功能,只需将以下内容添加到每个认证函数的末尾。

    if($sso = Yii::$app->getSession()->get('sso')){
    	return $this->redirect([
    		'discourse-sso', 
    		'sso' => $sso['sso'], 
    		'sig' => $sso['sig']
		]);
    }