首页 > 解决方案 > Angular将用户转移到登录屏幕

问题描述

我正在使用 Express 为我的应用程序提供降价文件。该应用程序需要使用带有 JWT 的 cookie 实现的身份验证。关键代码如下所示:

app.get('*.md',
  (req, res, next) => {
    if (fileIsPublic(req.path) || tokenIsValid(req.cookies[config.cookieName])) next();
    else {
      // console.log('doing redirect!', req.path);
      // res.redirect('/login');
      console.log('sending unauthorized', req.path);
      res.status(401).send({ message: 'no token' });
    }
});

简单地说,如果用户没有有效的令牌并试图访问非公共文件,那么客户端浏览器会收到 HTTP 401 错误。在客户端,代码如下所示:

    // ...
    } catch (err) {
      const he = err as HttpErrorResponse;
      console.log('document service got error', he);
      if (he.status === 401) this.router.navigate(['/login']);

只要客户端浏览器正在运行 Angular 应用程序,它就可以工作。但是,如果浏览器正在获取数据 URL(例如来自另一个站点的链接),那么用户只会看到 object { message: 'no token' }。Angular 应用程序永远不会运行,因此上述逻辑不适用。

如果我执行重定向(如上面注释掉的代码)来解决该问题,但它打破了应用程序正在运行的情况,因为当从服务器接收到 HTTP 302 响应时,应用程序永远不会看到它。相反,HttpClient get Observable 返回如果它请求重定向的 URL 开始时它会得到的响应。Angular 应用程序永远不会看到 302 响应,即使它会显示在开发人员窗口中。

所以我的情况是,如果客户端正在运行我的应用程序,或者客户端没有运行我的应用程序,但不能同时运行两者,我的代码就可以工作。

我觉得我错过了一些明显的东西,但有人知道如何解决这个问题吗?

标签: angularexpress

解决方案


我想出了一个我并不完全满意的解决方案,但我没有看到更好的解决方案。

关键是您必须在服务器上使用重定向方法。如果您不这样做,那么如果用户通过资产匹配的 URL 路径进入应用程序,那么 Angular 应用程序将永远没有机会加载。

在客户端,正如我提到的,302 响应永远不会被看到。但是确实发生的是HttpResponse对象确实获得了服务器指示的 URL 是重定向的目标,并且您可以分支出来。所以客户有:

      const resp = await this.http.get('assets/' + path,
                   { observe: 'response', responseType: 'text' }).toPromise();
      // console.log('document service pulled response', resp);
      if (resp.url.endsWith('/login')) {
        console.log('redirecting to login');
        this.router.navigate(['/login']);
      }

请注意,重定向不会导致get方法抛出任何东西。它只返回一个HttpResponse。我希望这对某人有所帮助。


推荐阅读