Log*_*per 5 vue.js openid-connect oidc-client-js vuejs3
我目前正在构建一个 Vue3 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);
}
});
Run Code Online (Sandbox Code Playgroud)
这个window.appConfig具有用于初始化UserManager的设置对象
这是我导出的 AuthService.ts 类。请注意我在 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();
}
Run Code Online (Sandbox Code Playgroud)
在我的 router/index.ts 文件中,我有以下内容
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;
Run Code Online (Sandbox Code Playgroud)
我的注销按钮非常简单
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();
}
}
Run Code Online (Sandbox Code Playgroud)
例如,我想要挂钩的事件之一是 addUserSignedIn 事件。但是,即使注销并重新登录,该事件也不会触发。我想使用此事件对用户数据进行一些基本初始化。关于为什么这些事件没有触发有什么想法吗?
这就是最终对我有用的东西。这是我的 AuthService.ts 类,在代码库中使用。
// 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();
}
}
Run Code Online (Sandbox Code Playgroud)
我的 config.json 中更新的 SSO 设置对象已传递给用户管理器
"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"
}
},
Run Code Online (Sandbox Code Playgroud)
为了完整起见,这里是我的callback.html 和silent-redirect.html 页面。这两个文件与 config.json 和 oidc-client-ts.min.js 文件一起放置在顶级公共文件夹中。
回调.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>
Run Code Online (Sandbox Code Playgroud)
静默更新.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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3274 次 |
| 最近记录: |