Comments (10)
@OZIOisgood Thank you for your response. I appreciate that.
I tried your code and enabled the ssr from angular.json file
Still getting the same issue.
If there is any other solution please do share with me.
Thank you.
from keycloak-angular.
Hi again, actually I have an issue with this method. Need to call keycloakService.getToken() in server side which doesn't work as we don't load keycloak in server side.
Is there any example of working keycloak in SSR mode? need to get token on server side.
from keycloak-angular.
Please, follow up.
I have the same issue.
ERROR ReferenceError: document is not defined
"keycloak-angular": "^15.2.1", "keycloak-js": "^24.0.3", "@angular/common": "^17.2.0", "@angular/compiler": "^17.2.0", "@angular/core": "^17.2.0",
from keycloak-angular.
@OZIOisgood Thank you for your response.
Here are my keycloak configurations
keycloak.config.ts i have put this file in src/environments folder
import { KeycloakConfig } from "keycloak-js";
const keycloakConfig: KeycloakConfig = {
URL: "<keycloak-url-here>",
realm: "<realm-here>",
clientId: "<client-id-here>",
};
export default keycloakConfig;
app.config.ts file
import { KeycloakAngularModule, KeycloakService } from "keycloak-angular";
import { APP_INITIALIZER } from "@angular/core";
export const appConfig: ApplicationConfig = {
providers: [
{ provide: APP_INITIALIZER, useFactory: initializer, multi: true, deps: [KeycloakService] },
KeycloakService,
importProvidersFrom(KeycloakAngularModule),
//other modules added
]
}
assets/silent-check-sso.html
<html>
<body>
<script>
parent.postMessage(location.href, location.origin);
</script>
</body>
</html>
keycloak-initializer.ts
import { environment } from "@env/environment";
import { KeycloakOptions, KeycloakService } from "keycloak-angular";
export function initializer(keycloak: KeycloakService): () => Promise<boolean> {
const options: KeycloakOptions = {
config: environment.keycloak,
initOptions: {
onLoad: "login-required",
checkLoginIframe: true,
},
enableBearerInterceptor: true,
bearerPrefix: "Bearer",
loadUserProfileAtStartUp: false,
bearerExcludedUrls: ["/assets", "/clients/public"],
shouldAddToken: (request) => {
const { method, url } = request;
const isGetRequest = "GET" === method.toUpperCase();
const acceptablePaths = ["/assets", "/clients/public"];
const isAcceptablePathMatch = acceptablePaths.some((path) => url.includes(path));
return !(isGetRequest && isAcceptablePathMatch);
},
shouldUpdateToken: (request) => {
return !request.headers.get("token-update") === false;
},
};
return () => keycloak.init(options);
}
auth.service.ts
import { Injectable } from "@angular/core";
import { KeycloakService } from "keycloak-angular";
import { KeycloakProfile, KeycloakTokenParsed } from "keycloak-js";
@Injectable({
providedIn: "root",
})
export class AuthService {
constructor(private keycloakService: KeycloakService) {}
public getLoggedUser(): KeycloakTokenParsed | undefined {
try {
const userDetails: KeycloakTokenParsed | undefined = this.keycloakService.getKeycloakInstance().idTokenParsed;
return userDetails;
} catch (e) {
console.error("Exception", e);
return undefined;
}
}
public isLoggedIn(): boolean {
return this.keycloakService.isLoggedIn();
}
public loadUserProfile(): Promise<KeycloakProfile> {
return this.keycloakService.loadUserProfile();
}
public login(): void {
this.keycloakService.login();
}
public logout(): void {
this.keycloakService.logout(window.location.origin);
}
public redirectToProfile(): void {
this.keycloakService.getKeycloakInstance().accountManagement();
}
public getRoles(): string[] {
return this.keycloakService.getUserRoles();
}
}
auth.guard.ts
import { Injectable } from "@angular/core";
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from "@angular/router";
import { KeycloakAuthGuard, KeycloakService } from "keycloak-angular";
@Injectable({
providedIn: "root",
})
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) {
// Force the user to log in if currently unauthenticated.
if (!this.authenticated) {
await this.keycloak.login({
redirectUri: window.location.origin + state.url,
});
}
// Get the roles required from the route.
const requiredRoles = route.data["roles"];
// Allow the user to proceed if no additional roles are required to access the route.
if (!Array.isArray(requiredRoles) || requiredRoles.length === 0) {
return true;
}
// Allow the user to proceed if all the required roles are present.
return requiredRoles.every((role) => this.roles.includes(role));
}
}
from keycloak-angular.
having the same problem with SSR and this config:
function initializeKeycloak(keycloak: KeycloakService) {
return () =>
keycloak.init({
config: {
url: 'http://localhost:8080',
realm: 'bizmatch',
clientId: 'bizmatch-angular-client'
},
initOptions: {
onLoad: 'check-sso',
silentCheckSsoRedirectUri: (<any>window).location.origin + '/assets/silent-check-sso.html'
},
bearerExcludedUrls: ['/assets'],
shouldUpdateToken(request) {
return request.headers.get('token-update') !== 'false';
}
});
}
getting an error: "window is not defined" instead of "document is not defined" ..
from keycloak-angular.
Just found a workaround (StackOverflow)
Add these lines to providers in app.config.ts file
KeycloakAngularModule,
KeycloakService,
{
provide: APP_INITIALIZER,
useFactory: initKeycloak,
multi: true,
deps: [KeycloakService],
},
and this is the initial function
import { KeycloakService } from 'keycloak-angular';
import { environment } from '../environments/environment';
declare var require: any;
const Keycloak = typeof window !== 'undefined' ? import('keycloak-js') : null;
export function initKeycloak(keycloak: KeycloakService) {
if (Keycloak !== null) {
return () =>
keycloak.init({
config: environment.keycloakConfig,
initOptions: {
onLoad: 'check-sso',
checkLoginIframe: false,
},
enableBearerInterceptor: true,
bearerPrefix: 'Bearer',
});
} else {
return () => {
return new Promise<Boolean>((resolve, reject) => {
resolve(true);
});
};
}
}
from keycloak-angular.
Hey, @sanjay-noknok
Could you provide us the configuration in your project(the way you have “implemented keycloak-angular”)
Maybe the problem is in the way how have you provided keycloak-angular things.
from keycloak-angular.
@sanjay-noknok
Guards and Interceptors should now be written as plain JavaScript function.
As of Angular 15 they have deprecated class-based guards and interceptors.
Maybe it is a problem, why you are facing some issues. Try to use function-based AuthGuard:
import { CanMatchFn, Router, UrlTree } from '@angular/router';
import { inject } from '@angular/core';
// Services
import { KeycloakService } from 'keycloak-angular';
export const authGuard: CanMatchFn = async (route, segments): Promise<boolean | UrlTree> => {
const router = inject(Router);
const keycloakService = inject(KeycloakService);
const authenticated: boolean = await keycloakService.isLoggedIn();
if (!authenticated) {
await keycloakService.login({
redirectUri: window.location.origin,
});
}
// Get the user Keycloak roles and the required from the route
const roles: string[] = keycloakService.getUserRoles(true);
const requiredRoles = route.data?.['roles'];
// Allow the user to proceed if no additional roles are required to access the route
if (!Array.isArray(requiredRoles) || requiredRoles.length === 0) {
return true;
}
// Allow the user to proceed if ALL of the required roles are present
const authorized = requiredRoles.every((role) => roles.includes(role));
// Allow the user to proceed if ONE of the required roles is present
//const authorized = requiredRoles.some((role) => roles.includes(role));
if (authorized) {
return true;
}
// Display my custom HTTP 403 access denied page
return router.createUrlTree(['/access']);
};
And Bearer Interceptor should be provided as:
export const appConfig: ApplicationConfig = {
providers: [
KeycloakService,
{
provide: APP_INITIALIZER,
useFactory: initializeKeycloak,
multi: true,
deps: [KeycloakService]
},
{
provide: HTTP_INTERCEPTORS,
useClass: KeycloakBearerInterceptor,
multi: true
},
provideRouter(routes),
provideHttpClient(withInterceptorsFromDi())
]
};
withInterceptorsFromDi()
is used here to specify that class-based Interceptor will be used, since there is no function-based one in angular-keycloak
yet.
from keycloak-angular.
same issue here withAngular 17 SSR enabled.
from keycloak-angular.
Related Issues (20)
- Support for Pure Function-Based Guards in Angular HOT 2
- Support for Keycloak v23 HOT 9
- The JSDoc for getToken states it calls updateToken if necessary, but it does not HOT 1
- How I would know when the session is expired? HOT 1
- Problem with KeycloakService in Angular 17 HOT 1
- KeycloakAuthGuard example HOT 4
- keycloakBearerInterceptorFn example HOT 1
- Login method locale is not changing the user locale when the user logs in
- angular crashes with check-sso
- Support KC 24.x.x HOT 6
- Catch sign out event or redirect to ssop event
- keycloak-angular - next version improvements HOT 1
- Bug in package.json version 15.2.0 HOT 3
- Keycloak setup for Single SPA angular Project
- HttpClient Interceptor not working HOT 1
- Configure updateToken minValidity in HTTP Interceptor
- Standalone bootstrap: withEnabledBlockingInitialNavigation() causes isLoggedIn() to return false in AuthGuard HOT 2
- Add setup instructions for standalone bootstrap
- Logout the user if he is idle
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from keycloak-angular.