#angular #openid-connect #oidc-client-js #oidc-client
#angular #OpenID-connect #oidc-client-js #oidc-client
Вопрос:
Я использую oidc-client.js
в своем angular
проекте.
Прямо сейчас пользователи могут входить и выходить из системы, и все работает нормально. единственная проблема заключается в том, что когда я хочу вызвать службу в app.component, в перехватчике пользователь не аутентифицируется.
auth.service является :
Injectable({
providedIn: 'root'
})
export class AuthService extends BaseService {
private _authNavStatusSource = new BehaviorSubject<boolean>(false);
authNavStatus$ = this._authNavStatusSource.asObservable();
private manager = new UserManager(getClientSettings());
private user: User | null;
constructor(private http: HttpClient) {
super();
this.manager.getUser().then(user => {
this.user = user;
this._authNavStatusSource.next(this.isAuthenticated());
});
}
login() {
return this.manager.signinRedirect();
}
async completeAuthentication() {
this.user = await this.manager.signinRedirectCallback();
this._authNavStatusSource.next(this.isAuthenticated());
}
isAuthenticated(): boolean {
return this.user != null amp;amp; !this.user.expired;
}
get authorizationHeaderValue(): string {
return `${this.user.token_type} ${this.user.access_token}`;
}
async signout() {
await this.manager.signoutRedirect();
}
}
export function getClientSettings(): UserManagerSettings {
return {
authority:environment.authApiURI,
client_id: 'medilloxdashboard',
redirect_uri: environment.redirect_uri,
post_logout_redirect_uri: environment.postLogoutRedirectUri,
response_type: "id_token token",
scope: "openid spa profile",
filterProtocolClaims: true,
loadUserInfo: true,
automaticSilentRenew: true,
silent_redirect_uri:environment.silentRedirectUri,
userStore: new WebStorageStateStore({ store: localStorage })
};
}
и я написал перехватчик для добавления токена ко всем подобным запросам :
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private authorizationHeader = "Authorization";
constructor(
private authService: AuthService,
private router: Router) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
headers: request.headers.set(this.authorizationHeader, this.authService.authorizationHeaderValue)
});
return next.handle(request);
}
}
AuthService
и AuthInterceptor
зарегистрированы в Core nodule
.
В App.Compoentn
я вызываю подобную службу, которая вызывает REST api
export class AppComponent implements OnInit {
title = 'myapp';
version: string;
constructor(
private router: Router,
private dashboardService: DashboardService) {
this.version = environment.version;
}
ngOnInit(): void {
this.dashboardService.getDashboards().subscribe();
}
}
когда происходит этот вызов, я получаю getDashboards failed: this.user is undefined
, но я вызываю именно эту службу в других компонентах, и она работает нормально.
компоненты, которые вызывают эту службу и получают результат, находятся в их модулях.
В чем проблема?
Ответ №1:
Попробуйте выполнить свой вызов внутри и ngAfterViewCheck
вместо ngOnInit
, потому что службы на данный момент еще не запущены. Будьте осторожны, это будет выполняться бесконечно. Вы можете продолжать выполнять вызов, пока пользователь не определен.
Комментарии:
1. В
ngAfterViewChecked
нем все в порядке, но этот код запускается всякий раз, когда я нажимаю на каждую кнопку. Есть ли лучший способ?2. мой ответ ниже (новый ответ стека)
Ответ №2:
Чтобы ответить на ваш вопрос @osman Rahimi «В ngAfterViewChecked все в порядке, но этот код запускается всякий раз, когда я нажимаю на каждую кнопку. Есть ли лучший способ?»
Ответ :
data: any;
ngAfterViewChecked (): void {
if(this.data === null || this.data === undefined) {
this.dashboardService.getDashboards().subscribe(data => this.data = data);
}
}
Комментарии:
1. Я опубликовал новый ответ, пожалуйста, проверьте, все ли в порядке или нет
Ответ №3:
Я создал Initializer
подобное
import { AuthService } from "./auth-service";
export function AuthInitializer(auth: AuthService) { return () => auth.isAuthenticated() };
и зарегистрирован так в core.module
providers: [
{
provide: APP_INITIALIZER,
useFactory: AuthInitializer,
deps: [AuthService],
multi: true
}]
это работает отлично.