多站點中,子站點設定了不同的域名,如何實現跨站登陸

標籤: 

正在檢視 5 個帖子:1-5 (共 5 個帖子)
  • 作者
    帖子
  • gnt-wordpress
    參與者
    • 文章數量: 49
    @gnt-wordpress
    樓主

    如題 多站點中,子站點設定了不同的域名,如何實現跨站登陸,不需要切換站點,又需要重新登陸

    殼殼蟲
    參與者
    • 文章數量: 328
    @kekechong

    要實現跨站登入,可以使用單點登入 (Single Sign-On,簡稱 SSO) 的方法。以下是一種實現方式:

    1. 在主站點上建立一個統一的使用者認證系統,可以是自己開發的,也可以使用現有的認證系統,如 OAuth 、 OpenID 等。
    2. 在子站點的登入頁面上新增一個登入按鈕或連結,指向主站點的登入頁面。
    3. 當使用者點選登入按鈕或連結時,跳轉到主站點的登入頁面。
    4. 在主站點的登入頁面上,使用者輸入使用者名稱和密碼進行登入認證。
    5. 主站點認證成功後,生成一個加密的令牌 (Token) 。
    6. 將令牌作為引數附加到回撥 URL 中,並將使用者重定向回子站點。
    7. 子站點接收到回撥 URL,並從中提取令牌。
    8. 子站點將令牌傳送到主站點進行驗證。
    9. 主站點驗證令牌的有效性後,返回使用者資訊給子站點。
    10. 子站點使用返回的使用者資訊進行登入操作,完成跨站登入。

    需要注意的是,為了實現跨站登入,主站點和子站點之間需要共享使用者認證資訊,可以使用共享資料庫、共享快取、共享會話等方式來實現。另外,為了保證安全性,令牌需要進行加密和簽名,防止被篡改或偽造。


    以上由殼殼蟲自動解答供參考,您可以繼續跟帖或等待人工回覆。

    詩語
    管理員
    • 文章數量: 5,928
    @feibisi

    這個問題我們也在除錯,之前有個 SSO 方案,但是年久失修,另一種解決方案就是做使用者瀏覽器 cookie 共享,我們還在測試。

    gnt-wordpress
    參與者
    • 文章數量: 49
    @gnt-wordpress
    樓主

    @feibisi 請問下大神,這個 cookie 共享的方案,現在咋樣了?

     

    詩語
    管理員
    • 文章數量: 5,928
    @feibisi

    嘗試把下面的程式碼加入到你的 mu-plugins 目錄裡,可以儲存為一個 php 檔案,就可以實現跨站登入。

    我們目前是實現了子站互通,之前的站群內建外掛已經太老舊了,新版本在開發,下面程式碼可以參考

    <?php
    
    if ( ! is_multisite() ) {
    	return;
    }
    
    function is_sso_site() {
    	return is_main_site();
    }
    
    function get_sso_login_url( $query_args = [] ) {
    	$query_args = wp_parse_args( 
    		$query_args,
    		[
    			'multisite_sso_blog_id' => get_current_blog_id(),
    		]
    	);
    
    	return add_query_arg( $query_args, network_site_url( 'wp-login.php', 'login' ) );
    }
    
    function get_sso_callback_url( $blog_id, $query_args = [] ) {
    	return add_query_arg( $query_args, get_site_url( $blog_id, 'wp-login.php', 'login' ) );
    }
    
    add_filter(
    	'login_message',
    	function ( $messages ) {
    		if ( is_user_logged_in() || is_sso_site() ) {
    			return;
    		}
    
    		$sso_args = [];
    
    		$redirect_to = filter_input( INPUT_GET, 'redirect_to', FILTER_SANITIZE_URL );
    		if ( $redirect_to ) {
    			$sso_args['redirect_to'] = rawurlencode( $redirect_to );
    		}
    
    		$messages .= '<style type="text/css">
    			.login .wp-multisite-sso-login--cta a { font-size:inherit; float:none; display:inline-block; width:100%; clear:both; text-align:center; }
    		</style>';
    
    		$messages .= sprintf(
    			'<div class="message wp-multisite-sso-login--cta">
    				<p><a href="%s" class="button button-primary button-large">%s</a></p>
    			</div>',
    			esc_url( get_sso_login_url( $sso_args ) ),
    			esc_html__( 'Login with Multisite SSO' ),
    		);
    
    		return $messages;
    	},
    	200
    );
    
    add_action(
    	'login_init',
    	function () {
    		if ( ! is_sso_site() || is_user_logged_in() ) {
    			return;
    		}
    
    		$blog_id = isset( $_REQUEST['multisite_sso_blog_id'] ) ? absint( $_REQUEST['multisite_sso_blog_id'] ) : null;
    
    		if ( empty( $blog_id ) ) {
    			return;
    		}
    
    		$blog = get_blog_details( $blog_id );
    
    		if ( ! $blog ) {
    			return;
    		}
    
    		add_action(
    			'login_form',
    			function () use ( $blog_id ) {
    				?>
    				<input type="hidden" name="multisite_sso_blog_id" value="<?php echo esc_attr( $blog_id ); ?>">
    				<?php
    			}
    		);
    
    		add_filter(
    			'wp_login_errors',
    			function ( $errors ) use ( $blog ) {
    				$message = sprintf( 
    					esc_html__( 'You are logging into %s' ), 
    					sprintf( 
    						'<a href="%s" target="_blank">%s</a>', 
    						esc_url( $blog->home ), 
    						esc_html( $blog->blogname ) 
    					)
    				);
    
    				$errors->add( 'multisite_sso_notice', $message, 'message' );
    
    				return $errors;
    			}
    		);
    	}
    );
    
    add_filter(
    	'login_redirect',
    	function ( $redirect_to, $requested_redirect_to, $user ) {
    		if ( ! is_sso_site() ) {
    			return $redirect_to;	
    		}
    
    		$blog_id = isset( $_REQUEST['multisite_sso_blog_id'] ) ? absint( $_REQUEST['multisite_sso_blog_id'] ) : null;
    
    		if ( ! empty( $blog_id ) && $user instanceof WP_User ) {
    			// Add the destination blog hostname to the allowed safe-redirect list.
    			add_filter(
    				'allowed_redirect_hosts',
    				function ( $hosts ) use ( $blog_id ) {
    					$hosts[] = wp_parse_url( get_site_url( $blog_id ), PHP_URL_HOST );
    					$hosts[] = wp_parse_url( get_home_url( $blog_id ), PHP_URL_HOST );
    
    					return $hosts;
    				}
    			);
    
    			$session_token = wp_generate_password( 42, false, false );
    
    			// Relay the private session token through a back-channel.
    			update_user_meta( $user->ID, 'multisite_sso_token', $session_token );
    
    			$args = [
    				'multisite_sso_user_id' => $user->ID,
    				'multisite_sso_token' => wp_hash( $session_token ), // Transfer hashed for one-time verification.
    			];
    
    			if ( ! empty( $requested_redirect_to ) && $redirect_to !== $requested_redirect_to ) {
    				$args['redirect_to'] = urlencode( $requested_redirect_to );
    			}
    
    			return get_sso_callback_url( $blog_id, $args );
    		}
    
    		return $redirect_to;
    	},
    	100,
    	3
    );
    
    add_action(
    	'login_init',
    	function () {
    		if ( is_sso_site() || is_user_logged_in() ) {
    			return;
    		}
    		
    		$login_user_id = isset( $_GET['multisite_sso_user_id'] ) ? absint( $_GET['multisite_sso_user_id'] ) : null;
    		$login_token_hash = isset( $_GET['multisite_sso_token'] ) ? sanitize_text_field( $_GET['multisite_sso_token'] ) : null;
    
    		if ( ! $login_user_id || ! $login_token_hash ) {
    			return;
    		}
    
    		// Get the session token from the SSO source and delete it to ensure it is used only once.
    		$token_source = get_user_meta( $login_user_id, 'multisite_sso_token', true );
    		delete_user_meta( $login_user_id, 'multisite_sso_token' );
    
    		if ( $token_source && hash_equals( wp_hash( $token_source ), $login_token_hash ) ) {
    			wp_clear_auth_cookie();
    			wp_set_auth_cookie( $login_user_id );
    			wp_set_current_user( $login_user_id );
    
    			$redirect_to = filter_input( INPUT_GET, 'redirect_to', FILTER_SANITIZE_URL );
    			if ( ! $redirect_to ) {
    				$redirect_to = get_dashboard_url( $login_user_id );
    			}
    
    			wp_redirect( $redirect_to );
    			exit;
    		}
    	}
    );
正在檢視 5 個帖子:1-5 (共 5 個帖子)
  • 哎呀,回覆話題必需登入。

話題資訊

  • 當前位於:疑難雜症
  • 4 條回覆
  • 3 個參與人
  • 最後回覆:<a href="https://bbs.weixiaoduo.com/users/feibisi/" title=" 檢視詩語的個人資料" class="bbp-author-link"><span class="bbp-author-name"> 詩語</span></a>
  • 上次活動:<a href="https://bbs.weixiaoduo.com/topic/42604/#post-45010" title=" 回覆至:多站點中,子站點設定了不同的域名,如何實現跨站登陸">4 月、 2 周前</a>