Javascript 通过UserManager使用服务时,用户为Null

Javascript 通过UserManager使用服务时,用户为Null,javascript,angular,typescript,ecmascript-6,single-page-application,Javascript,Angular,Typescript,Ecmascript 6,Single Page Application,使用Angular 7和我创建了一个AuthService,它公开了一些UserManager方法 当我从AuthService调用SignInDirectCallback时,用户为null 如果我直接使用UserManager调用它,则用户不是null 详情如下: const settings : UserManagerSettings = { authority: 'https://localhost:5005', client_id: 'spa', redirect_uri:

使用Angular 7和我创建了一个AuthService,它公开了一些UserManager方法

当我从AuthService调用
SignInDirectCallback
时,用户为
null

如果我直接使用UserManager调用它,则用户不是
null

详情如下:

const settings : UserManagerSettings = {
  authority: 'https://localhost:5005',
  client_id: 'spa',
  redirect_uri: 'https://localhost:5001/signin',
  post_logout_redirect_uri: 'https://localhost:5001/signout',
  response_mode: 'query',
  response_type: 'code',
  scope: 'openid profile email offline_access api',
  filterProtocolClaims: true,
  loadUserInfo: true
};

@Injectable({ 
  providedIn: 'root' 
})

export class AuthService {

  private manager = new UserManager(settings);
  private user: User = null;

  constructor() {

    this.manager.getUser().then(user => {
      this.user = user;
    });

  }

  isSignedIn(): boolean {
    return this.user != null && !this.user.expired;
  }

  getClaims(): any {
    return this.user.profile;
  }

  signInRedirect(args?: any): Promise<void> {
    return this.manager.signinRedirect(args);
  }

  signInRedirectCallback(url?: string): Promise<void> {
    return this.manager.signinRedirectCallback(url).then(user => {
      this.user = user;
    });
  }

 // Other methods

}
那么我的回调组件如下所示:

import { Component, OnInit } from '@angular/core';

import { AuthService } from '../shared/services/auth.service'
import { UserManagerSettings, UserManager } from 'oidc-client';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'signin',
  templateUrl: './signin.component.html'
})

export class SignInComponent implements OnInit {
  private manager = new UserManager(settings);
  constructor(private authService: AuthService, private router: Router) { }

  ngOnInit() {
    this.manager.signinRedirectCallback().then(function (user) {
       console.log(user);
    });
  }
}
当我使用
console.log(user)
时,回调组件上的
user
未定义

为了实现这一点,我需要在SignInComponent(回调组件)上创建一个新的UserManager,而不是使用AuthService,例如:

const settings : UserManagerSettings = {
  authority: 'https://localhost:5005',
  client_id: 'spa',
  redirect_uri: 'https://localhost:5001/signin',
  post_logout_redirect_uri: 'https://localhost:5001/signout',
  response_mode: 'query',
  response_type: 'code',
  scope: 'openid profile email offline_access api',
  filterProtocolClaims: true,
  loadUserInfo: true
};

@Component({
  selector: 'signin',
  templateUrl: './signin.component.html'
})

export class SignInComponent implements OnInit {

  private manager = new UserManager(settings);

  constructor(private router: Router) { }

  ngOnInit() {

    this.manager.signinRedirectCallback().then(function (user) {
      console.log(user);
   });

  }

}
知道为什么会这样吗?我错过了什么

谢谢你

没什么好尝试的

将您的响应类型更改为此

response_type: 'id_token token'
并删除用户中的null

private user: User;
然后取下这两个

response_mode

@Injectable({ 
  providedIn: 'root' 
})
需要检查的两件事:

  • 首先,打开浏览器控制台,查看
    signInDirectCallback()调用
    是否抛出任何错误
  • 其次,查看应用程序的会话存储,您是否看到由身份验证流填充的任何用户数据
另一个观察:您不应该为每个页面创建
UserManager
的实例;oauth与
oidc客户机的所有逻辑应封装在

将在应用程序的不同页面中注入的服务。

isSignedIn
方法更改为基于承诺

 isSignedIn(): Promise<boolean> {
    return new Promise((resolve, reject) => {
      this.manager.getUser().then(user => {
        resolve(user != null && !user.expired);
      });
    });
  }
isSignedIn():承诺{
返回新承诺((解决、拒绝)=>{
this.manager.getUser().then(user=>{
解析(user!=null&&!user.expired);
});
});
}
还有你的路线守卫:

canActivate(): Promise<boolean> {
    return new Promise((resolve, reject) => {
      this.authService.isLoggedIn().then(result => {
        if (result) {
          resolve(result);
        } else {
          this.authService.startAuthentication().finally(() => {
            reject(false);
          });
        }
      });
    });
  }
canActivate():承诺{
返回新承诺((解决、拒绝)=>{
this.authService.isLoggedIn().then(结果=>{
如果(结果){
决心(结果);
}否则{
this.authService.startAuthentication().finally(()=>{
拒绝(假);
});
}
});
});
}

AuthService构造函数正在调用异步函数,但尚未响应,您已开始测试“用户”如何解决此问题?“响应类型:'id\u token token'”仅适用于混合流,不应在SPA上使用。
canActivate(): Promise<boolean> {
    return new Promise((resolve, reject) => {
      this.authService.isLoggedIn().then(result => {
        if (result) {
          resolve(result);
        } else {
          this.authService.startAuthentication().finally(() => {
            reject(false);
          });
        }
      });
    });
  }