【问题标题】:How to chain redirects in Node/Express如何在 Node/Express 中链接重定向
【发布时间】:2016-01-21 07:06:31
【问题描述】:

我试图实现的行为是,当节点应用程序重定向到一个 URL 时,一旦完成,我希望节点应用程序随后重定向到另一个 URL。

res.redirect('/hello').then(res.redirect('/'))

类似的东西。

我想要实现的是,当用户从我的应用程序中注销时,他们首先会被重定向到我们的身份服务器,这会清除与用户和身份服务器的任何关联,将他们完全注销,然后重定向到特定于应用程序的登录名(在节点应用程序中配置的路径)。因此,

res.redirect('www.identityserver.com/logout').then(res.direct('www.application.com/auth'))

限制是我无法使用构建身份服务器的注销后重定向 URL 来实现这一点......仅仅是因为我们不想升级到最新版本。此外 - 在应用程序中手动清除其 cookie/会话,然后将它们重定向到 www.application.com/auth 并不能完全取消对它们的身份验证。身份服务器仍然知道它们并将它们与某些会话/cookie 相关联。

注意:这个问题没有好的答案,但我尽最大努力选择了答案。

【问题讨论】:

  • 你为什么要这样做?
  • 为什么还要尝试重定向两次?一个给定的 http 响应只能有一个重定向位置。您显然误解了重定向的工作原理。这是返回给浏览器的单个 http 响应,它告诉浏览器下一步该去哪里。然后,浏览器将发出一个新请求来加载该新位置,并且该新请求与当前响应无关。
  • 您尝试做的事情表明您不了解服务器端重定向的工作原理。请查看我在之前的评论中添加的内容。您必须重定向到 /logout 然后在那个请求处理程序中,您可以再次重定向。而且,要仅为该用户执行此操作,您必须在会话类型中设置一些内容,以便您可以识别该用户何时再次回来。
  • @jfriend00 你的意思是来自身份服务器的请求处理程序吗?我知道您来自哪里,但我无法控制修改身份服务器
  • 是的。您正在将浏览器发送到该其他服务器。当您重定向到该注销页面时,浏览器要做的下一件事就是从该服务器获取一个页面并加载它。您现有的服务器不再与该浏览器有任何关系。如果您不控制注销页面或注销服务器,则您无法告诉浏览器在该页面之后去哪里。

标签: node.js express promise


【解决方案1】:

这里有一个关于如何做到这一点的想法。

将您的重定向更改为您自己的特殊重定向页面。在该重定向页面中,您包含一个指向 http://www.identityserver.com/logout 页面的 iframe。只要登出页面不包含反框架逻辑,这样就应该实现登出。

现在,由于注销 iframe 来自与您的页面不同的域并且您无法控制它,因此如果没有 iframe 内部的合作,您将无法与 iframe 的内容进行通信。因此,假设 iframe 没有合作,您将无法知道何时完成注销。但是,你可能真的不需要知道这一点。您需要做的是确保 iframe 有足够的时间发送它的初始请求,以便身份服务器主机可以接收该注销请求。您可以测试这可能需要多长时间,但如果您在此特殊页面完成加载后开始测量时间,那么几秒钟可能足以确保已发送 iframe 注销请求。

然后,在那几秒钟之后,您可以将您的特殊页面重定向到您想要访问的任何新页面。如果您要测量从页面加载时开始的时间,那么您可能希望通过设置从该页面中的客户端 Javascript 执行此重定向:

window.location = "http://www.application.com/auth";

现在,您甚至不必加载特殊页面来完成所有这些操作或直接涉及服务器。您可以使用客户端 Javascript 创建注销 iframe,然后将其插入到您已经在其中的任何页面中。这两种方式都可以完成。


至于您最初的想法,来自同一个服务器响应的两个重定向的概念在概念上是有缺陷的(这在 cmets 中已经大部分解释过,但我会在这里总结一下)。

服务器端重定向由响应中的自定义标头组成,该标头指定要转到的新位置,以及告诉请求者应该执行重定向的特定响应状态。根据定义,这个结构只能保存一个重定向。而且,一旦发生重定向,浏览器就会转到新服务器上的新页面,并且该服务器对该浏览器的影响不再为零。所以,一旦你重定向到注销服务器,你就不能再影响事情了。这完全取决于该注销服务器及其提供的页面接下来会发生什么。

【讨论】:

    【解决方案2】:

    正如上面的 cmets 建议的那样,您可能不想这样做,但无论如何我都会回答您的问题,因为它可能会帮助您理解原因。

    您可以像这样设置一系列重定向:

    app.get('/start', function(req, res) {
        console.log('start');
        res.redirect('/hello');
    });
    
    app.get('/hello', function(req, res) {
        console.log('hello');
        res.redirect('/');
    });
    
    app.get('/', function(req, res) {
        console.log('/');
        res.end();
    });
    

    但请注意,这里的重定向根本没有真正的用处。 / 路由最终在链末端所做的任何事情都可以简单地由 /start 路由预先处理,无需重定向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-11
      • 2018-01-21
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多