mauriciovigolo / keycloak-angular

Easy Keycloak setup for Angular applications.
MIT License
730 stars 280 forks source link

HttpClient Interceptor not working #556

Closed majuabir closed 7 months ago

majuabir commented 7 months ago

Bug Report or Feature Request (mark with an x)

- [ x] bug report -> please search for issues before submitting
- [ ] feature request

Versions.

Angular: 17.3.1 Keycloak-angular: 15.2.1 Keycloak: 22.0.5

Repro steps.

The HttpClient Interceptor appears to not add the Authorization: Bearer header to my requests to my backend server. I have this setup below. What might I be doing wrong?

function initConfig(
    acs: AppConfigService,
    keycloak: KeycloakService,
) {

    return async () => {
        keycloak.keycloakEvents$.subscribe(kcEvent => {
            console.log("subscribe fired");
            console.log(kcEvent);
            if (kcEvent.type == KeycloakEventType.OnTokenExpired) {
                console.log("subscribe redirect")
                window.location.href = '/login';
            }
        });

        const tokenFromCookie = Cookies.get('token');
        const refreshTokenFromCookie = Cookies.get('refreshToken');

        await acs.loadConfig();
        keycloak.init({
            config: {
                url: `https://${acs.getConfig().AUTH_DOMAIN}/auth`,
                realm: 'test_realm',
                clientId: 'test_client',
            },
            initOptions: {
                token: tokenFromCookie,
                refreshToken: refreshTokenFromCookie,
                onLoad: 'check-sso',
                silentCheckSsoRedirectUri:
                    window.location.origin + '/assets/silent-check-sso.html'
            },
            enableBearerInterceptor: true,
            bearerPrefix: 'Bearer',
            bearerExcludedUrls: []
        })
        .then(() => {
            console.log('(Auth) Token initialized successfully');
        })
        .catch(() => {
            console.log('(Auth) Could not initialize keycloak');
        });
    }
}

...

bootstrapApplication(AppComponent, {
    providers: [
        provideRouter(routes),
        provideAnimations(),
        provideHttpClient(withInterceptorsFromDi()),
        importProvidersFrom(KeycloakAngularModule),
        {
            provide: APP_INITIALIZER,
            useFactory: initConfig,
            deps: [
                AppConfigService,
                KeycloakService
            ],
            multi: true,
        },
        {
            provide: HTTP_INTERCEPTORS,
            useClass: KeycloakBearerInterceptor,
            multi: true
        }
    ],
}).catch(err => console.error(err));

For making requests to my backend I have this wrapper function that I invoke here:

makeRequest(
        method: 'DELETE' | 'GET' | 'HEAD' | 'JSONP' | 'OPTIONS' | 'POST' | 'PUT' | 'PATCH',
        endpoint: string,
        data?: any,
        headers?: HttpHeaders
    ) {
        let request = new HttpRequest<any>(
            method,
            `https://${this.acs.getConfig().BACKEND_DOMAIN}${endpoint}`,
            data,
            { headers: headers }
        );

        request = request.clone({
            headers: request.headers
                .append('x-rest-call', `true`),
        });

        const httpEventStream = this.http.request<any>(request);
        return httpEventStream;
    }

The log given by the failure.

Desired functionality.

The Authorization: Bearer header is automatically applied to requests to my backend server.

majuabir commented 7 months ago

It works now somehow. Maybe I misremembered building it or something I'm not sure. As far as I know the code as seen functions.

JustDoItSascha commented 3 months ago

Hey! I have the exact same issue right now. Should I create new issue for it?

P.S. Fixed it. For other people using Angular 18, you have to do:

provideHttpClient(withInterceptorsFromDi()),