问题描述:在使用Angular和oidc-client-js进行静默续约时,发现在多个标签页中无法正常工作。
解决方法: 这个问题通常是由于多个标签页共享同一个会话状态引起的。为了解决这个问题,可以使用LocalStorage或SessionStorage来存储会话状态,并在每个标签页中进行同步。
以下是一个解决方法的代码示例:
auth.service.ts
的新服务文件,并添加以下代码:import { Injectable } from '@angular/core';
import { UserManager, User } from 'oidc-client';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private userManager: UserManager;
constructor() {
this.userManager = new UserManager({
// OIDC配置
authority: 'https://your-auth-server.com',
client_id: 'your-client-id',
redirect_uri: 'https://localhost:4200/signin-callback',
post_logout_redirect_uri: 'https://localhost:4200/signout-callback',
response_type: 'id_token token',
scope: 'openid profile',
silent_redirect_uri: 'https://localhost:4200/assets/silent-callback.html',
automaticSilentRenew: true,
filterProtocolClaims: true,
loadUserInfo: true
});
}
public getUser(): Promise {
return this.userManager.getUser();
}
public renewToken(): Promise {
return this.userManager.signinSilent();
}
}
app.component.ts
文件中,添加以下代码来处理多个标签页的同步问题:import { Component, OnInit } from '@angular/core';
import { AuthService } from './auth.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
constructor(private authService: AuthService) { }
ngOnInit() {
// 在每一个标签页中监听storage事件
window.addEventListener('storage', () => {
// 如果storage中的某个键值发生变化
if (event.key === 'oidc.user:{your-client-id}') {
// 调用续约方法
this.authService.renewToken().then(user => {
// 处理续约成功的逻辑
}).catch(error => {
// 处理续约失败的逻辑
});
}
});
}
}
silent-callback.html
文件中,添加以下代码:
这样,当一个标签页接收到来自其他标签页的storage事件时,就会调用续约方法来更新会话状态。同时,在silent-callback.html
页面中设置一个随机值,可以触发storage事件。
请注意,上述代码中的your-client-id
需要替换为你的实际客户端ID。
希望这个解决方法能帮助到你解决问题!