Vue.js oidc-client-ts UserManager事件未触发



我目前正在构建一个ve3 SPA,并尝试使用oidc-client-ts javascript库对用户进行身份验证。到目前为止,我已经成功地用现有代码实现了登录/注销功能。我遇到的问题是,我无法挂钩到UserManager提供的addUserLoaded或addUserSignedIn事件(https://authts.github.io/oidc-client-ts/classes/UserManagerEvents.html)。有一点要注意的是,当你登陆我的域名时,我们会说myapp.mydomain.com,你会被重定向到我们的身份服务器myid.mydomain.com,然后在成功登录后重定向回来。



在启动时,我有以下内容

fetch("config.json", {'method': "GET"})
.then(response => { 
if(response.ok) {
response.json().then(appConfigData => {
window.appConfig = appConfigData;
createApp(App)
.use(store)
.use(router)
.use(AccordionPlugin)
.component("font-awesome-icon", FontAwesomeIcon)
.mount("#app");
});    
} else{
alert("Server returned " + response.status + " : " + response.statusText);
}                
});

这个窗口。appConfig有用于初始化UserManager的settings对象



这是我的AuthService。我导出的这个类。请注意我在构造函数中注册到UserManager的事件。

import { UserManager, WebStorageStateStore, User, UserManagerEvents } from "oidc-client-ts";
import jwt_decode from "jwt-decode";
import store from "@/store";
export default class AuthService {
private userManager: UserManager;
constructor(configuration: any) {
const IDP_URL: string = configuration.IDP_URL;
const REDIRECT_URI: string = configuration.REDIRECT_URI;
const AUTH_TOKEN_URI: string = configuration.AUTH_TOKEN_URI;
const CLIENT_ID: string = configuration.CLIENT_ID;
const SILENT_RENEW_REDIRECT_URI: string = configuration.SILENT_RENEW_REDIRECT_URI;
const POPUP_REDIRECT_URI: string = configuration.POPUP_REDIRECT_URI;
const settings: any = {
userStore: new WebStorageStateStore({ store: window.localStorage }),
authority: IDP_URL,
client_id: CLIENT_ID,
redirect_uri: REDIRECT_URI,
popup_redirect_uri: POPUP_REDIRECT_URI,
response_type: "code",
automaticSilentRenew: true,
silent_redirect_uri: SILENT_RENEW_REDIRECT_URI,
scope: "openid profile ContactCenterApi.READ_WRITE",
post_logout_redirect_uri: AUTH_TOKEN_URI,
loadUserInfo: true
};
this.userManager = new UserManager(settings);
this.userManager.events.addUserLoaded(_args => {
console.log("USER LOADED EVENT");
debugger;
this.userManager.getUser().then(usr => {
store.dispatch("getProducts", usr?.profile.sub) // load the users products
});
});
this.userManager.events.addUserSignedIn(() => {
console.log("USER SIGNED IN EVENT");
debugger;
this.userManager.getUser().then(usr => {
store.dispatch("getProducts", usr?.profile.sub) // load the users products
});
});
}
public getUser(): Promise<User|null> {
return this.userManager.getUser();
}
public async login(): Promise<void> {
return this.userManager.signinRedirect();
}
public logout(): Promise<void> {
return this.userManager.signoutRedirect();
}


在我的路由器/索引。我有以下

const auth = new AuthService(window.appConfig);
router.beforeEach(async (to, from, next) => {
const user = await auth.getUser();
const baseUri = window.appConfig.BASE_URI + "/#";
console.log("redirectedUri = " + baseUri + to.fullPath);
if (user) {
if (!user.expired) {
next();
} else {
sessionStorage.setItem("redirectedUri", baseUri + to.fullPath);
await auth.login();
}
} else {
sessionStorage.setItem("redirectedUri", baseUri + to.fullPath);
await auth.login();
}
});
export default router;


我的注销按钮是非常基本的

import  AuthService  from "@/auth/AuthService";
onselect: async function(event: MenuEventArgs) {
var authService = new AuthService(window.appConfig); // settings are stored in the window when the app mounts
if(event.item.text === 'Logout') {
await authService.logout();
}
}

例如,我想要钩入的事件之一是addUserSignedIn事件。然而,即使在注销和重新登录时,该事件也不会触发。我想使用这个事件对用户数据进行一些基本的初始化。你知道为什么这些事件没有发生吗?

这是我最终成功的方法。这是我的AuthService。在代码库周围使用的类。

// AuthService.ts
import { UserManager, WebStorageStateStore, User } from "oidc-client-ts";
import jwt_decode from "jwt-decode";
import store from "@/store";

let userManager: UserManager;

const currentURL = document.location.origin;
fetch(currentURL + "/config.json", { 'method': "GET" })
.then(config => {
config.json()
.then(configuration => {
configuration['SSO_SETTINGS']['userStore'] = new WebStorageStateStore({ store: window.localStorage });
userManager = new UserManager(configuration['SSO_SETTINGS']);

userManager.events.addUserLoaded(newUser => {
console.log("USER LOADED EVENT");
userManager.storeUser(newUser);
userManager.getUser().then(usr => {
store.dispatch("getUserInfo", usr?.profile.sub) // load the user from my api
});
});

userManager.events.addAccessTokenExpired(() => {
userManager.signoutRedirect();
})

userManager.events.addSilentRenewError(error => {
console.log("ERROR RENEWING ACCESS TOKEN.");
console.log(error);
})
})
})
export default class AuthService {
public static getUser(): Promise<User | null> {
return userManager.getUser();
}
public static async login(): Promise<void> {
return userManager.signinRedirect();
}
public static logout(): Promise<void> {
localStorage.clear();
sessionStorage.clear();
return userManager.signoutRedirect();
}
}

我的配置中更新的SSO设置对象。传递给用户管理器的Json

"SSO_SETTINGS": {
"userStore": "",
"authority": "https://myauthorityurl.com",
"client_id": "MyClientName",
"redirect_uri": "http://localhost:8080/callback.html",
"response_type": "code",
"response_mode": "query",
"automaticSilentRenew": true,
"monitorSession": true,
"silent_redirect_uri": "http://localhost:8080/silent-renew.html",
"scope": "openid profile",
"post_logout_redirect_uri": "http://localhost:8080",
"loadUserInfo": true,
"metadata": {
"issuer": "https://myauthorityurl.com",
"jwks_uri": "https://myauthorityurl.com/.well-known/openid-configuration/jwks",
"authorization_endpoint": "https://myauthorityurl.com/connect/authorize",
"end_session_endpoint": "https://myauthorityurl/Account/Logout",
"token_endpoint": "https://iddev02.carexm.com/connect/token",
"userinfo_endpoint": "https://iddev02.carexm.com/connect/userinfo"
}
},

为了完整起见,这里是我的callback.html和silent-redirect.html页面。这两个文件与您的配置一起放在顶级公共文件夹中。

callback.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Waiting...</title>
</head>
<body>
<script src="oidc-client-ts.min.js"></script>
<script>
var config = fetch("config.json", {'method': "GET"})
.then(config =>
{
config.json().then(settings => {
var mgr = new oidc.UserManager(settings['SSO_SETTINGS']);
mgr.settings.userStore = new oidc.WebStorageStateStore({ store: window.localStorage });
mgr.signinRedirectCallback()
.then(() =>
{ 
window.location.href = sessionStorage.getItem("redirectedUri") ?? "../";
})
})
});
</script>
</body>
</html>

silent-renew.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Waiting...</title>
</head>
<body>
<script src="oidc-client-ts.min.js"></script>
<script>
var config = fetch("config.json", {'method': "GET"})
.then(config =>
{
config.json().then(settings => {
var mgr = new oidc.UserManager(settings['SSO_SETTINGS']).signinSilentCallback();
})
});
</script>
</body>
</html>

最新更新