我正在尝试在MERN SPA中实现社交登录功能,以便用户可以使用他们的Google/Facebook/Twitter/等登录我的网站。登录。这显然是一个非常常见的场景,并且有大量的帖子和示例讨论如何使用各种身份验证流(即授权代码流,PKCE授权代码流等)来完成此任务。
然而,对于我试图实现的流(下面描述),我无法弄清楚如何处理从身份提供者重定向回来而不导致用户代理刷新和丢失状态。
例如,这里是我试图实现与谷歌登录的流程:
-
用户点击"使用google登录";按钮,将用户代理定向到Google的授权端点。
-
Google验证用户并将其重定向回我的重定向URI并提供授权码。
-
用户代理向我的站点后端调用API,提供授权码。
-
我的站点后端发送授权码到谷歌的令牌端点(连同我的应用程序的
client_id
和client_secret
),获取回ID令牌,创建合适的JWT,并返回JWT回用户代理。 -
用户代理存储JWT并将其作为承载令牌发送回服务器。
我的问题在第二步。由于这一步导致浏览器重新加载我的SPA,因此React组件中的状态被清除。我可以使用localStorage
部分解决这个问题,但这会增加复杂性。
是否有可能实现这个流没有浏览器不得不重新加载我的应用程序和清除组件状态?或者,我是否应该使用其他方法来绕过这个明显的陷阱?
(我是React/spa和OIDC的新手,所以请原谅任何明显的误解或疏忽。)
SPA将重载它的index.html,因此在这些操作之后重新启动应用程序,你无法阻止:
- 初始页面加载
- 收到OIDC响应
- 用户重新加载页面,例如通过cmd+R或F5
- 用户在应用程序中打开一个新的浏览器选项卡
- 收到注销响应
通常的技术是让SPA在发出OIDC重定向之前存储状态,包括其当前位置,例如/products/2
。然后,在每次页面加载时,检查当前URL是否表示OIDC响应(例如包含代码和状态查询参数)。如果是,那么从流中执行步骤3,然后从应用的存储状态恢复。
如果有帮助的话,这里是我的一些React代码,通过将当前位置存储在会话存储中来完成这种类型的事情。