Angular上的Keycloak - 加载时没有得到正确的状态

Posted

技术标签:

【中文标题】Angular上的Keycloak - 加载时没有得到正确的状态【英文标题】:Keycloak on Angular - not getting correct status on load 【发布时间】:2021-05-29 11:13:02 【问题描述】:

使用最新的 angular (11)、最新的 keycloak-angular 和 keycloak-js。

在页面加载时,当我初始化 keycloak 时,我想获得登录状态。即使会话处于活动状态,我总是会出错。

这是我的初始化代码:

import  KeycloakService  from 'keycloak-angular';
import  AppService  from 'src/app/app.service';
import  environment  from '../environments/environment';
 
export function initializer(keycloak: KeycloakService, appService: AppService): () => Promise<any> 
    return (): Promise<any> => 
        return new Promise<void>(async (resolve, reject) => 
          try 
            await keycloak.init(
                config: 
                    url: environment.keycloak.issuer,
                    realm: environment.keycloak.realm,
                    clientId: environment.keycloak.clientId
                ,
              loadUserProfileAtStartUp: true,
              initOptions: 
                checkLoginIframe: true
              ,
              bearerExcludedUrls: []
            ).then((a) => 
              console.log(a); // this returns always false
            );
            resolve();
           catch (error) 
            reject(error);
          
        );
      ;

即使在以下情况下也会返回 false:

【问题讨论】:

【参考方案1】:

正如我在 cmets 中所写,我发现我必须拥有 onLoad 属性。 我不想有onLoad: 'login-required',因为大多数页面不需要用户登录,所以我不得不添加onLoad: 'check-sso'

【讨论】:

【参考方案2】:

请尝试使用这种初始化方法:

export function initializer(keycloak: KeycloakService): () => Promise<any> 
return (): Promise<any> => 
  return new Promise(async (resolve, reject) => 
    try 
      await keycloak.init(
        config: 
                url: environment.keycloak.issuer,
                realm: environment.keycloak.realm,
                clientId: environment.keycloak.clientId
            ,
        initOptions: 
          onLoad: 'check-sso',
          checkLoginIframe: false
        ,
        enableBearerInterceptor: true,
        bearerPrefix: 'Bearer',
        bearerExcludedUrls: [
          'main.js',
        ]
      );
      resolve();
     catch (error) 
      reject(error);
    
  
    )
    .catch((e) => 
      console.log('Error thrown in init ' + e);
    );
;

【讨论】:

解决方案是添加:onLoad: 'check-sso'。谢谢你的帮助。【参考方案3】:

我会说它首先需要带有 pkce 流的授权代码,因为它是 SPA(当然使用的 OIDC 客户端必须是公共的):

initOptions: 
  onLoad: 'login-required',
  checkLoginIframe: false,
  pkceMethod: 'S256'
,

async/await 语法也可能是个问题(但 Angular/JS 不是我的菜,所以我可能是错的)。我会将其重写为:

keycloak.init(
  ...
).then(async authenticated => 
  if (!authenticated) 
    // unauthenticated
    console.log(a)
    window.location.reload()
    return
   else 
    // authenticated
    console.log(a)
    ...
  

【讨论】:

这行不通。它现在一直在重新加载窗口。 @FilipWitkowski 当然,有一百万个变量,您的问题中没有提到,始终提供***.com/help/minimal-reproducible-example 以获得最佳答案。我强调了一些我可以看到的问题,但您还有其他问题。 我通过添加 onLoad: 'check-sso' 来修复它。我不确定这是否是正确的解决方案,但它现在有效。我不想使用“需要登录”,因为用户无需登录即可访问大部分页面。

以上是关于Angular上的Keycloak - 加载时没有得到正确的状态的主要内容,如果未能解决你的问题,请参考以下文章

Angular/Keycloak:415 不支持的媒体类型

Keycloak 用户角色 Angular 和 .net 核心

Keycloak + Spring Cloud Gateway + Angular 9

Aurelia Keycloak 集成

Angular - Spring Boot - Keycloak - 401错误

为啥 Angular 无法识别用户是不是使用 keycloak 登录?