配置 OIDC 客戶端
在項目中創建 authOptions
對象,定義 OIDC 認證所需的配置項:
export const authOptions = {authority: 'https://xxxxxxxxx/UserCenter', // 認證服務器 URLclient_id: 'xxxx', // 客戶端 IDredirect_uri: 'http://localhost:3000/callback', // 登錄回調地址response_type: 'code', // 授權類型scope: 'IF.DataMaster.Writer IF.DataMaster.Reader IF.DataMaster.Modeler IF.DataMaster.Web', // 權限范圍post_logout_redirect_uri: 'https://localhost:3000/', // 登出后重定向地址client_secret: 'xxxxxxxxxxx', // 客戶端密鑰
};
創建 OIDC 用戶管理器
封裝 UserManager
實例,管理用戶認證狀態:
import { OidcClientSettings, UserManager } from 'oidc-client-ts';const userManager = ref<UserManager>();
const oidcSettings = ref<OidcClientSettings>();export async function useUserManager(): Promise<UserManager | undefined> {if (userManager.value) {return userManager.value;}const settings = authOptions;if (settings) {oidcSettings.value = settings;userManager.value = new UserManager(settings);return userManager.value;}return undefined;
}
登錄邏輯
調用 signinRedirect
發起 OIDC 登錄:
export async function signinlogin() {useUserManager().then((mgr) => {if (mgr) {mgr.signinRedirect();}});
}
處理登錄回調
在回調頁面解析用戶信息并獲取 Token:
async function signinCallback() {try {const mgr = await useUserManager();if (!mgr) return null;await mgr.signinCallback();const user = await mgr.getUser();const jwt_token = user?.access_token;if (!jwt_token) return null;const cc_token = await getTokenByJWTString(jwt_token);if (cc_token.startsWith('err@')) {message.error('OIDC 登錄失敗');return null;}return cc_token;} catch (error) {return Promise.reject(error);}
}
路由守衛集成
在路由守衛中檢查 Token,未登錄時觸發 OIDC 登錄:
export function createPermissionGuard(router: Router) {const userStore = useUserStoreWithOut();router.beforeEach(async (to, from, next) => {const token = userStore.getToken;if (!token && !to.meta.ignoreAuth) {signinlogin(); // 觸發 OIDC 登錄return;}next();});
}
Hash 路由兼容處理
若使用 Hash 路由,需在回調后清理 URL:
function createRedirectPageGuard(router: Router) {const userStore = useUserStore();router.beforeEach(async (to, _from, next) => {if (window.location.href.includes('/callback?')) {const token = await userStore.signinCallback();userStore.setToken(token as string);const { origin, pathname } = window.location;window.location.href = origin + pathname; // 清理回調參數return;}next();});
}
關鍵點說明
authority
:OIDC 認證服務器地址。client_id
和client_secret
:需與認證服務器配置一致。signinCallback
:必須在回調頁面調用以完成登錄流程。- Hash 路由:需手動清理
#
后的回調參數,避免路由沖突。
通過上述步驟,可實現基于 oidc-client-ts
的單點登錄集成。