【问题标题】:Update Angular2 Service boolean before routing after bootstrapping引导后在路由之前更新 Angular2 服务布尔值
【发布时间】:2016-08-25 16:43:59
【问题描述】:

我将 Angular2 与 ASP.NET Core MVC 一起使用,并且管理手动 URL 导航工作正常,服务器正在使用 Angular2 成功加载我的主页视图。

在用户身份验证时,我正在设置一个这样的会话变量:

HttpHelper.HttpContext.Session.SetString("isLoggedIn", true.ToString() );

我想要的是,在用户进入应用程序之后,如果他想通过手动导航来加载特定路由,我希望我的服务调用我的 ASP 控制器来检查用户是否已经通过身份验证,以便我的后卫允许路由。相反,守卫默认设置为 false,我显然会被重定向到我的登录页面。

这是我要调用的 ASP 控制器方法来更新我的 auth.service 中的 IsLoggedIn 值:

[HttpGet]
public IActionResult IsConnectedState()
{
    if (!String.IsNullOrWhiteSpace(HttpHelper.HttpContext.Session.GetString("isLoggedIn")))
        return Ok(true);
    else
        return Ok(false);
}

以便我的 AuthenticationGuard 可以调用 AuthenticationService 来更新管理已验证状态的布尔值: 编辑:粘贴整个 auth.guard.ts 代码以获得更清晰的解释

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
    if (!this.authService.isLoggedIn) {
        this.authService.setupLoggedInState().subscribe(() => {
            alert("guard check : " + this.authService.isLoggedIn);
            });
        }
    }

    canActivate()
    {
        if (this.authService.isLoggedIn) {
            return true;
        }

        this.router.navigate(['/login']);
        return false;
    }
}

使用以下代码更新我的 auth.service 中的布尔值:

setupLoggedInState() {
    alert("Setting Up");

    // Setting up the Http call 
    let lControllerAction: string = "/IsConnectedState";
    let lControllerFullURL: string = this.controllerURL + lControllerAction;
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    // Call my ASP Controller IsConnectedState() method
    return this.http.get(lControllerFullURL, options)
        .map((res: any) => {
            // Réponse reçue du WebService
            let data = res.json();
            alert(data);
            if (data == true) {
                this.isLoggedIn = true;
            }
        }
        ).catch(this.handleError);
}

当我尝试手动加载受保护的路由时,问题出现了,在我的服务中的布尔值更新之前,我被重定向到登录页面。我不知道我可以设置什么样的解决方案来解决这个问题...

我试着打电话

if (!this.authService.isLoggedIn) {
    this.authService.setupLoggedInState().subscribe(() => { });
}
  • 在我的守卫构造函数中
  • 在我的服务构造函数中

但它仍然没有在正确的时刻这样做。 我最好的猜测是在我加载我的第一个 AppModule 时管理它,但即使这可能是正确的时刻,我也不能保证我的布尔值会在 Angular2 完成引导时更新,并且执行同步 Http 调用似乎是一个非常糟糕的解决方案,因为它会阻止浏览器...... 任何想法都会很有帮助。

PS:我今天发了一个类似的帖子,但它是针对不同的问题,所以我将它链接到这里以避免混淆:Managing user authenticated state on manual URL navigation

【问题讨论】:

  • 您需要返回一个布尔值或从守卫发出布尔值的可观察对象。你在哪里做这个?
  • 如果我正确理解您的要求,我会在 AuthGuard 的 cosntructor 中执行此操作以调用 SetupLoggedInState() 方法,该方法将对我的 ASP 控制器进行 Http.Get 调用,然后更新我的 AuthService 布尔值.我会相应地编辑帖子
  • 或者我根本不明白你问了什么,但是更新我的服务的布尔值可以正常工作,只是它完成得太晚了,因为值在我被重定向到后更新登录页面,这是不正确的行为。当 MVC 后备路由加载我的视图引导 Angular2 时,我希望在那里更新服务布尔值,以便我的 authGuard 让我在路由器接管并尝试加载受保护的路由之前访问所需的路由。

标签: angular asp.net-core-mvc angular2-routing angular2-guards


【解决方案1】:

调用subscribe() 不会自动给出值。如果这调用了对服务器的请求,则在响应到达之前需要 loooong 时间。浏览器继续执行您的代码,当最终来自服务器的响应到达时,传递给 subscribe(...) 的回调被 observable 调用。您需要通过从 canActivate() 返回 observable 让 AuthGuard 等待 observable 或实际上是路由器,以便路由器可以等待 observable 发出响应。

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
  canActivate() {
    return this.authService.checkLoggedIn
    .map(loggedIn => {
      if(loggedIn) {
        return true;
      } else {
        this.router.navigate(['/login']); // not tried myself to navigate here
        return false;
      }
    });
  }
}


@Injectable()
class LoginService {
  constructor(private http:Http) {}

  checkLoggeIn() {
    return.http.get(someUrl).map(val => val.json());
  }
}

有关如何缓存 HTTP 请求结果的更多详细信息,请参阅What is the correct way to share the result of an Angular 2 Http network call in RxJs 5?

【讨论】:

  • 我会调查一下,感谢您的回答,我会尽快尝试并提供反馈
  • 嗯,我尝试设置您的解决方案,但是我正确导入的地图运算符出现此错误... import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map' "属性映射在 Observable 类型上不存在 奇怪的是我的 .map 运算符在我的其他文件中工作......?
  • 抱歉,无法从这些信息中判断。该错误似乎与我的回答无关,而是与您的本地项目设置有关。
  • 这只是因为我忘记了方法调用后的 ()... return this.authService.checkLoggedIn() .map(loggedIn => {
  • 现在我也看到了 ;-) 很高兴听到你想通了。
猜你喜欢
  • 1970-01-01
  • 2012-06-25
  • 2016-09-01
  • 1970-01-01
  • 2017-05-15
  • 2018-07-22
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多