Angular + oauth2 问题,auth 守卫总是在 API 仍在获取时调用 initLoginFlow

问题描述

我有一个应用程序,它使用 angular-oauth2-oidc调用 oauth 服务器,在获取 access_token 后,我将使用此令牌调用 Java 后端以获取用户配置文件。现在我面临的问题是应用程序不会等待 java http 请求完成,并且总是将我重定向到 oauth 登录页面。请参阅以下内容

app.component.ts

const authCodeFlowConfig: AuthConfig = {
  issuer: 'http://localhost:8888/openam/oauth2',redirectUri: 'http://localhost:4200',clientId: 'client',responseType: 'code',scope: 'openid profile',showDebuginformation: true,loginUrl: 'http://localhost:8888/openam/oauth2/authorize',tokenEndpoint: 'http://localhost:8888/openam/oauth2/access_token',}

@Component({
  selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.scss']
})
export class AppComponent {
  constructor(private oauthService: OAuthService,private userService: UserService) {
    this.oauthService.configure(authCodeFlowConfig);
    this.userService.runInitialLoginSequence();
  }
}

user.service.ts

@Injectable({
    providedIn: 'root'
})
export class UserService {

    private loggedInSubject = new BehaviorSubject<boolean>(false);
    public isLoggedOn$ = this.loggedInSubject.asObservable();

    private isAuthenticatedSubject = new BehaviorSubject<boolean>(false);
    public isAuthenticated$ = this.isAuthenticatedSubject.asObservable();

    constructor(private http: HttpClient,private oauthService: OAuthService) {

// check if getting token from oauth server,if yes,set loggedInSubject to true
      this.oauthService.events
        .pipe(filter(e => ['token_received'].includes(e.type)))
        .subscribe(() => {
          console.log('token received');
          if (this.oauthService.hasValidAccesstoken()) {
            this.loggedInSubject.next(true);
          }
        });

// check if user already pass oauth authentication,call fetchProfile()
      this.isLoggedOn$.subscribe(isLoggedOn => {
        if(isLoggedOn) {
          
          // subscribe http call,if getting user profile back,set isAuthenticatedSubject to true
          this.fetchProfile().subscribe(res => {
            if(res) {
              this.isAuthenticatedSubject.next(true);
              window.sessionStorage['profile'] = res
            }
          })
        }
      });
    }

// fetch user profile from Java backend
    public fetchProfile(): Observable<any> {
        let auth = "Bearer " + this.oauthService.getAccesstoken();
        let headers: HttpHeaders = new HttpHeaders()
            .set("Authorization",auth);

        // http request goes here,return observable
        return this.http.get(environment.ENDPOINT + "/profile",{
            headers: headers
        });
    }

// try login goes here
    public runInitialLoginSequence(): Promise<void> {
      return this.oauthService.tryLoginCodeFlow();
    }

// init login goes here
    public login(): void {
      this.oauthService.initLoginFlow();
    }

auth-guard.service.ts

@Injectable({
  providedIn: 'root'
})
export class AuthGuardService implements CanActivate {

  constructor(private userService: UserService,private router: Router,private oauthService: OAuthService) {
  }

  canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot) {

// before the http request complete,the app will always redirect me to oauth login page due to isAuthenticated is always false. it will change to true after the call is finished.
    return this.userService.isAuthenticated$.pipe(
      tap(isAuthenticated => isAuthenticated || this.userService.login()),)
  }

}

非常感谢

ps。配置文件未存储在 oauth 服务器中,因此我不会调用 /userinfo

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...