问题描述
我有问题,我想问问是否有人可以帮助我:)
在我的应用程序中有一个config.json文件,其中包含一些取决于阶段的信息(例如dev,IN,Prod ...)。
{
"queryUrl": "http://localhost:4200","commandUrl": "http://localhost:8282","ssoUrl": "https:someurlcode","ssoRealm": "someRealm","ssoClient": "dev"
}
在构建应用程序后,我希望交换此文件,因为在不同阶段它是不同的。 (在Jenkins Build中效果很好)
现在,我编写了一个Keycloak服务,在其中创建令牌:
import { Injectable } from '@angular/core';
// @ts-ignore
import Keycloak from 'keycloak-js';
// @ts-ignore
import * as config from '../../../assets/config.json';
@Injectable({
providedIn: 'root'
})
export class KeycloakService {
private keycloakAuth: any;
private ssoUrl: string;
private ssoRealm: string;
private ssoClient: string;
constructor() {
this.ssoUrl = config.ssoUrl;
this.ssoRealm = config.ssoRealm;
this.ssoClient = config.ssoClient;
}
init(): Promise<any> {
console.log('init ' + this.ssoClient);
return new Promise((resolve,reject) => {
this.keycloakAuth = Keycloak({
url: this.ssoUrl,realm: this.ssoRealm,clientId: this.ssoClient
});
this.keycloakAuth.init({ onLoad: 'login-required' })
.then(() => {
console.log('keycloak success');
resolve();
})
.catch(() => {
console.log('keycloak error');
reject();
});
});
}
getToken(): string {
return this.keycloakAuth.token;
}
}
您可能会看到,我是通过import语句加载Json的。如果我现在交换文件,它仍然会使用旧文件->猜想,因为它是在构建时获取的。
接下来这是我的http拦截器:
import {Injectable} from '@angular/core';
import {HttpErrorResponse,HttpEvent,HttpHandler,HttpInterceptor,HttpRequest} from '@angular/common/http';
import {KeycloakService} from './keycloak.service';
import {Observable,throwError} from 'rxjs';
import {catchError,retry} from 'rxjs/operators';
import {Router} from '@angular/router';
/**
* Passes on the KeyCloak token
*/
@Injectable()
export class KeycloakInterceptor implements HttpInterceptor {
constructor(private kcService: KeycloakService,private router: Router) {}
intercept(request: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
const authToken = this.kcService.getToken() || '';
request = request.clone({
setHeaders: {
Authorization: 'Bearer ' + authToken
}
});
return next.handle(request).pipe(
retry(1),catchError((error: HttpErrorResponse) => {
if (error.status !== undefined) {
this.router.navigate(['/error'],{queryParams: {errorCode: error.status}});
} else {
return throwError(error);
}
})
);
}
}
,还有来自app.module.ts
的一些见解 {
provide: APP_INITIALIZER,useFactory: keycloakFactory,deps: [KeycloakService],multi: true
},{
provide: HTTP_INTERCEPTORS,useClass: KeycloakInterceptor,multi: true
}
....
export function keycloakFactory(keycloakService: KeycloakService) {
return () => keycloakService.init();
}
我尝试了几次,以将其加载到init函数等中,但是总是出现未定义等错误……
希望有人可以帮助我...
干杯杰克
解决方法
Configuration.js
window.securityConfiguration = {
security: {
"queryUrl": "http://localhost:4200","commandUrl": "http://localhost:8282","ssoUrl": "https:someurlcode","ssoRealm": "someRealm","ssoClient": "dev"
}
};
然后在您的应用程序中
return new Promise((resolve,reject) => {
this.keycloakAuth = Keycloak({
url: window.securityConfiguration.ssoUrl,realm: window.securityConfiguration.ssoRealm,clientId: window.securityConfiguration.ssoClient
});