Next.js+Redux 认证和重定向

Posted

技术标签:

【中文标题】Next.js+Redux 认证和重定向【英文标题】:Next.js+Redux authentication and redirect 【发布时间】:2020-03-30 06:56:10 【问题描述】:

我开始构建一个 next.js 应用程序,我正在使用 redux。 我在 next.js 中阅读了很多关于身份验证的内容,特别是关于 redux 的内容。 假设我有一个 /login 页面和一个 /private 页面。 我的 redux 商店包含 isAuthenticated 状态。 所以,在我看来,我需要考虑以下场景:

    当通过地址栏 (s-s-r) 导航到 /private 时,我应该重定向到 /login。

    当已经在 /private 并且 isAuthenticated 更改为 false 时。

    在/login登录成功后,更新isAuthenticated状态,重定向到/private页面。

我是否错过了一些重要的可能场景(用户体验和安全方面)?

关于这些案例,我有几个问题想请教专家:

    对于场景 1,我在 getinitialprops 中实现了身份验证检查(仅当 ctx.req 不为空时)。如果用户未通过身份验证,我会使用 302 响应将他重定向到 /login 页面。可以吗?

    关于场景 2,我应该在哪里实现这个逻辑?最佳做法是什么?我可以考虑在 getinitialprops、render() 函数、componentDidUpdate 中实现检查...

    我应该在调用 redux 操作(身份验证)后重定向,还是在 redux 操作中重定向?

    我应该从 redux 操作中还是在组件的句柄函数中触发登录请求,并在成功时调用 redux 操作。

    重定向时,应该使用Router.push还是Router.replace?

请帮助我一劳永逸地了解最佳做法。

【问题讨论】:

【参考方案1】:

这是基于经验:

    对于场景 1,我在 getinitialprops 中实现了身份验证检查(仅当 ctx.req 不为空时)。如果用户未通过身份验证,我会使用 302 响应将他重定向到 /login 页面。可以吗?

是的,没关系。它会做它需要做的事情。

    关于场景 2,我应该在哪里实现这个逻辑?最佳做法是什么?我可以考虑在 getinitialprops、render() 函数、componentDidUpdate 中实现检查...

肯定是getInitialProps。我们所做的是我们制作了一个可以被 s-s-r 和 CSR 组件使用的助手。助手所做的是访问两个实例的 Cookie,这样,身份验证状态是一致的。可能有更好的方法,但我们就是这样实现的。

    我应该在调用 redux 操作(身份验证)后重定向,还是在 redux 操作中重定向?

取决于您团队的协议。对我们来说,所有的副作用,比如重定向,都可以在 Redux Sagas 中完成。

    我应该从 redux 操作中还是在组件的句柄函数中触发登录请求,并在成功时调用 redux 操作。

我建议使用 Sagas,因为它更清洁,并为您提供了另一层来保持所有副作用。但在您的情况下,我建议保持操作干净,只做需要做的事情:改变状态。

    重定向时,应该使用Router.push还是Router.replace?

我建议Router.push。使用 replace 会覆盖路由堆栈的顶部,这可能会在回击或不回击时导致不良影响。这将取决于您的要求,如果它担心您回击时会发生什么。

不要使事情过于复杂。让它发挥作用,并在实际使事情发挥作用后找到更好的方法。

【讨论】:

感谢 Edrian 的详细评论!关于您对 2 的回答: 1) getInitialProps 将在状态更改时运行? 2) 出于安全原因,我的 cookie (JWT) 无法从 JS (HttpOnly) 访问。我所做的是,对于服务器的每个请求,它都会检查 JWT 并更新 redux 存储。那是服务器端。但是对于客户端,我无法在 HOC 中检查 cookie 是否存在,我可以检查 Redux 商店的 isAuthenticated 状态吗?还是我应该再添加一个(不安全的)cookie 以获得客户端帮助?我真的不知道。我现在肯定会调查 redux saga... 顺便说一句,我正在使用 redux-thunk。你认为我应该转向 redux-saga 吗? 回答您的问题: 1) 不,getInitialProps 只会在页面的初始加载时运行。 2)如果你真的需要那么严格,那么据我所知,你需要调用你的服务器来检查你是否经过身份验证,这将是一件痛苦的事情。但如果没有,将您的 cookie 暴露给您的客户将使事情变得更容易。就像我说的,不要把事情复杂化。做有效的事。对于从 thunk 迁移到 redux-saga 的问题,我认为您不应该迁移到 Saga,因为在某种程度上,它们解决了同样的问题。只是不同的实现。 关于 2,为什么不检查 isAuthenticated 的存储状态?我在服务器请求中更新存储。因此,如果客户端询问 /private 并且他未通过身份验证,它将获得 302 重定向到 /login。这是安全方面的(对于需要保护的每个请求,我都会检查客户端是否经过身份验证)。 UX 方面,我使用 useEffect 钩子(在每个页面中)并在那里检查 redux 状态,如果它不适合,则重定向用户。如我所见,如果用户没有尝试奇怪的事情,则 useEffect 中的重定向只会在 redux 状态更改时发生(例如用户注销)。这不是为了安全。 我明白了。我们的应用程序就是这种情况,因为我们所做的身份验证是围绕 cookie 构建的。在某种程度上,它更像是一种偏好,而不是特定的身份验证方法。什么作品都行。如果您当前的设置适合​​您,那很好。如果我们在身份验证方面使用 cookie 作为唯一的事实来源,我们会发现每个人都更容易。

以上是关于Next.js+Redux 认证和重定向的主要内容,如果未能解决你的问题,请参考以下文章

使用react redux登录后重定向用户?

在 AWS amplify 中重写和重定向

React 路由器路径验证和重定向

无法在 firebase 重定向结果中使用 Redux 道具

SpringMVC框架如何实现请求转发和重定向呢?

Next.js 重定向/验证