Open fabiopacheco18 opened 2 years ago
Hi @fabiopacheco18
You can get the bearer token by using KeycloakService.getToken()
. Note that it returns Promise
I had the same problem too. I was able to get it to work after adding
{ provide: HTTP_INTERCEPTORS, useClass: KeycloakBearerInterceptor, multi: true },
to the providers of my app.module.ts.
I had not to do this before and I think this should happen automatically. Has something changed in angular beginning with version 13 or the last keycloak-angular updates?
Angular Version: "13.3.9", "keycloak-angular": "10.0.2", "keycloak-js": "18.0.1",
Tested and works with following packages version. Hope it can help you in case you have not found a solution:
export function initKeycloakInstance(keycloak: KeycloakService): () => Promise<boolean> {
return (): Promise<boolean> => {
return new Promise(async (resolve, reject) => {
try {
await keycloak.init({
config: {
url: '<KEYCLOAK_URL>',
realm: '<REALM>',
clientId: '<CLIENT_ID>'
},
initOptions: {
onLoad: 'login-required',
checkLoginIframe: false
},
enableBearerInterceptor: true, // attach ACCESS_TOKEN on each request
bearerPrefix: 'Bearer', // prefix "bearer <TOKEN> on each request
bearerExcludedUrls: []
});
resolve(true);
} catch (error) {
reject(error);
}
});
};
}
Hey folks,
I wanted to share a code snippet that worked well for me.
Versions. "keycloak-angular": "15.0.0" "keycloak-js": "22.0.5" "Angular": "17.0.4"
// app.config.ts
import {APP_INITIALIZER, ApplicationConfig, Provider} from '@angular/core';
import {provideRouter} from '@angular/router';
import {routes} from './app.routes';
import {KeycloakBearerInterceptor, KeycloakService} from "keycloak-angular";
import {HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi} from "@angular/common/http";
// Function to initialize Keycloak with the necessary configurations
function initializeKeycloak(keycloak: KeycloakService) {
return () =>
keycloak.init({
// Configuration details for Keycloak
config: {
url: 'http://localhost:1234/auth', // URL of the Keycloak server
realm: 'test', // Realm to be used in Keycloak
clientId: 'frontend' // Client ID for the application in Keycloak
},
// Options for Keycloak initialization
initOptions: {
onLoad: 'check-sso', // Action to take on load
silentCheckSsoRedirectUri:
window.location.origin + '/assets/silent-check-sso.html' // URI for silent SSO checks
},
// Enables Bearer interceptor
enableBearerInterceptor: true,
// Prefix for the Bearer token
bearerPrefix: 'Bearer',
// URLs excluded from Bearer token addition (empty by default)
//bearerExcludedUrls: []
});
}
// Provider for Keycloak Bearer Interceptor
const KeycloakBearerInterceptorProvider: Provider = {
provide: HTTP_INTERCEPTORS,
useClass: KeycloakBearerInterceptor,
multi: true
};
// Provider for Keycloak Initialization
const KeycloakInitializerProvider: Provider = {
provide: APP_INITIALIZER,
useFactory: initializeKeycloak,
multi: true,
deps: [KeycloakService]
}
// Exported configuration for the application
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withInterceptorsFromDi()), // Provides HttpClient with interceptors
KeycloakInitializerProvider, // Initializes Keycloak
KeycloakBearerInterceptorProvider, // Provides Keycloak Bearer Interceptor
KeycloakService, // Service for Keycloak
provideRouter(routes) // Provides routing for the application
]
};
@Michae1Weiss
Like prior to v17 was good enough to run following Initializer before application loads and enableBearerInterceptor: true was enough.
const KeycloakInitializerProvider: Provider = {
provide: APP_INITIALIZER,
useFactory: initializeKeycloak,
multi: true,
deps: [KeycloakService]
}
Now do we specifically need to enable todo?
// Provider for Keycloak Bearer Interceptor
const KeycloakBearerInterceptorProvider: Provider = {
provide: HTTP_INTERCEPTORS,
useClass: KeycloakBearerInterceptor,
multi: true
};
As you can see my solution for v.13 https://github.com/mauriciovigolo/keycloak-angular/issues/384#issuecomment-1850331808
Thanks @Michae1Weiss 👍 Same answer works with me using angular 17 and keycloak 23 I have only changed onLoad: 'login-required'
Why does it give me the following errors?
TypeError: ke.data.kernel.save.user_init is not a function kernel.js:376:37
TypeError: undefined is not a functionkernel.js:540:44
function initializeKeycloak(keycloak: KeycloakService) {
return () => keycloak.init({
config: {
url: environment.keycloak.keyclockUrl,
realm: environment.keycloak.realmId,
clientId: environment.keycloak.clientId
},
loadUserProfileAtStartUp: true,
initOptions: {
onLoad: 'login-required',
// onLoad: 'check-sso',
// flow: "standard",
silentCheckSsoRedirectUri: window.location.origin + '/assets/silent-check-sso.html',
checkLoginIframe: false,
redirectUri: environment.keycloak.redirectUri,
},
enableBearerInterceptor: true,
bearerExcludedUrls: [
'/student-registration', // Exclude this path
'/student-registration/*'],
bearerPrefix: 'Bearer',
}).then((authenticated) => {
if (authenticated) {
const token = keycloak.getKeycloakInstance().token;
if (token) {
try {
localStorage.setItem('token', token);
} catch (error) {
console.error('Error decoding token:', error);
}
} else {
console.error('Access token is undefined');
}
} else {
console.log('Authentication failed');
keycloak.login();
}
// Subscribe to Keycloak events to handle token expiration
keycloak.keycloakEvents$.subscribe({
next(event) {
if (event.type === KeycloakEventType.OnTokenExpired) {
keycloak.updateToken(20).then((refreshed) => {
if (refreshed) {
console.log('Token was successfully refreshed');
} else {
console.warn('Token is still valid');
}
}).catch(() => {
console.error('Failed to refresh token, logging out');
keycloak.logout();
});
}
}
});
});
}
i wantend to exclude path but it did not work , please have any idea about that please guide me
and this routes.path export const APP_ROUTE: Route[] = [ { path: 'student-registration', redirectTo: '/student-registration/student-registration' },
{
path: '',
component: MainLayoutComponent,
canActivate: [AuthGuard],
children: [
{ path: '', redirectTo: '/authentication/signin', pathMatch: 'full' },
}]
auth.guard
export class AuthGuard extends KeycloakAuthGuard {
constructor(
protected override readonly router: Router,
protected readonly keycloak: KeycloakService
) {
super(router, keycloak);
}
public async isAccessAllowed(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise
// If the user is not authenticated, redirect to Keycloak login
if (!this.authenticated) {
await this.keycloak.login({
redirectUri: window.location.origin + state.url,
});
return false;
}
// Check if route has required roles
const requiredRoles = (route.data as { roles: string[] }).roles;
if (!Array.isArray(requiredRoles) || requiredRoles.length === 0) {
return true; // Allow if no roles are required
}
// Ensure the user has all required roles
return requiredRoles.every((role) => this.roles.includes(role));
}
Bug Report or Feature Request (mark with an
x
)Versions.
"keycloak-angular": "9.1.0" "keycloak-js": "16.0.0" "Angular": "13.0.2"
i'm trying to implement keycloak-angular but i'm not able to add the bearer token by default to my http requests.
app.module.ts