解决angular 单点登录时后端返回的url中不可以携带 #

230 阅读1分钟

问题

单点登录时,后端返回的url中不可以携带 # ,携带的#会被编码成为%23,导致前端路由加载时,识别路由识别,重定向到默认路由,重定向时携带的参数信息消失,在应用默认页面获取不到参数信息

解决

在应用初始化时,获取url信息,判断是否为单点,如果为单点进行后续处理

原理

在NG里面,我们要使用一个服务,那么就会通过providers来创建或者获取服务的实例,providers现在有多种类型可以选择

TypeProvider | ValueProvider | ClassProvider | ConstructorProvider | ExistingProvider | FactoryProvider | any[];

具体代码

app.module.ts (使用FactoryProvider)

import { AppConfig, initializer } from "./icb/utils/app-init";
import { LayoutService } from "./icb/layout/layout.service";
...
providers: [
    AppConfig,
    LayoutService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializer,
      deps: [AppConfig, LayoutService],
      multi: true,
    },
  ],
 ...
  • APP_INITIALIZER是Angular提供的依赖注入令牌,可以在Angular应用程序初始化过程中注入一些自定义逻辑。
  • // 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、
      // OpaqueToken的实例或字符串
      provide: any;
      // 设置用于创建对象的工厂函数
      useFactory: Function;
      // 依赖对象列表
      deps?: any[];
      // 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖
      // 对象列表
      multi?: boolean;
    

app-init.ts

export function initializer(
  appConnfig: AppConfig,
  commonService: CommonService
): Function {
  return () => appConnfig.init(commonService);
}
​
@Injectable()
export class AppConfig {
  private router: Router;
​
  constructor(
    private keycloak: KeycloakService,
    private cookieService: CookiesService,
    injector: Injector
  ) {
    setTimeout(() => {
      this.router = injector.get(Router);
    });
  }
​
  public init(commonService: CommonService) {
    return new Promise(async (resolve, reject) => {
      await commonService
        .getConfig("application")
        .toPromise()
        .then((application) => {
          Environment.application = application;
        });
      try {
       // something....
           await layoutService.init();
        resolve();
      } catch (error) {
        reject(error);
      }
    });
  }
}

layoutService.ts

...
init(): Promise<any> {
    let localUrl = window.location.href;
    let host = window.location.origin + window.location.pathname;
    return new Promise((resolve, reject) => {
      if (localUrl.indexOf("code=") < 0) {
        resolve(true);
      } else {
        if (localUrl.indexOf("code=") >= 0) {
          let code = this.getUrlParam("code");
          this.ssoLogin(code).subscribe(res => {
            sessionStorage.setItem("token", res.token);
            sessionStorage.setItem("USER_INFO", JSON.stringify(res));
            // this.router.navigate([`/home`]);
            window.location.href = host + "#/home";
            resolve(true);
          }, error => {
            resolve(true);
          });
        } else {
          resolve(true);
        }
      }
    });
  }
...

\