具有oauth登录的SPA的最佳实践
我有一个Vue应用,我正在使用nodejs和MySQL作为后端。我想用Google,Facebook和本地登录来实现登录。
我花了数小时的时间阅读文档和教程,我很难把最好的方法和最佳实践结合起来。我尝试了很多可以成功登录的npm软件包,但是它们当然没有连接到服务器端,而从客户端(弹出窗口)发起请求时,服务器端库(例如passwordjs)似乎不能很好地发挥作用。至少我无法使其正常工作。
我希望登录可以在单独的窗口中进行,并且成功登录后用户将停留在同一页面上,并且页面状态得以保留。
有人知道我如何通过对后端的验证请求并尽可能简单地做到这一点〜100%安全吗?
谢谢
回答如下:免责声明:我只为公司系统实现了oauth流,该系统似乎总是以某种方式违反库中的流,因此习惯于手动实现这些流。这篇文章旨在让您掌握oauth的工作方式,发生的不同流程以及基本指南,以了解您在何处需要哪些信息。
据我所知,普通的Web应用程序通常使用三个Oauth流程,即:
- 使用授权码的流被交换为访问令牌]
- 直接返回访问令牌的流。
- 需要用户在您的网站上输入用户名和密码的流量,然后在您的后端将其交换为访问令牌
还有更多的oauth流程,但此处不相关。您可以阅读有关它们的更多信息on the website oauth。
对于具有自己的前端和后端的应用程序,授权代码是必经之路。对于仅具有前端且没有您控制的api的应用程序,仅具有访问令牌的流非常有用。第三种选择是有风险的,因为(例如)您要让人们在example上输入其Google凭据。您可以信守诺言,仅用此内容完成oauth流程...或者您不能假冒用户。前两个流程将登录过程与您要验证的站点分开,仅通过令牌共享访问权限。
让您的后端信任令牌
由于具有前端和后端,请选择将返回授权代码的流程。由于您在其他站点上输入凭据,因此经常涉及重定向。
- 您的应用从Oauth提供者打开一个页面,定义一个重定向URL。有时您定义两个,一个代表成功,一个代表失败。
- 用户在Oauth提供者的页面上输入其凭据
- Oauth提供者 生成授权令牌,并使用授权令牌重定向到重定向URL
要让您的后端信任用户就是他们声称的用户,您需要将授权令牌获取到您的后端。您可以通过输入直接指向您的api的重定向URL或输入指向您自己的应用程序的重定向url来实现,然后该应用程序将检索并将授权令牌传递给您的api。
验证特定用户
通常,您希望api中的用户概念与Oauth完全分开,这既是因为您不想在每次需要有关用户的信息时都必须查询Oauth提供程序,也因为它在实施新的Oauth提供程序或您自己的用户名/密码方案时,可以使您的生活更加轻松。这意味着,就您的Vue应用程序而言,仅当您的api表示对用户进行身份验证时,才对用户进行身份验证。当用户具有允许其发出api请求的Bearer令牌或cookie时,它知道用户已通过身份验证。您的Vue应用程序并不关心Bearer令牌或cookie的产生方式。
对于您的后端,您需要神奇地决定必须认证哪个用户。在上一节中,我们讨论了将授权令牌传递到后端的问题。无论您使用什么,都需要完成以下任务:
- 与Oauth提供者交换授权令牌以获取访问令牌。您可以通过从后端直接向oauth提供商进行http请求来做到这一点。 oauth提供者将使用访问令牌进行响应。您可以使用此访问令牌获取有关用户的信息。
- 使用具有访问令牌的Oauth提供程序进行调用以获取在数据库中找到正确用户所需的任何信息
- 如果找到了用户,则现在可以为该用户创建承载令牌或会话。如果找不到用户,则可以创建一个用户,提示用户创建一个用户或出错。
- 将不记名令牌或会话cookie返回到前端。如果您进行了api调用以传递授权令牌,那么该令牌将为您切出。如果您输入的是api网址作为重定向网址,则必须以某种方式传递此信息。可能最简单的方法是重定向到应用程序中的特定页面,该页面需要令牌并将其存储在某个位置。
使它与弹出窗口一起工作
通过弹出窗口完成所有这些工作比较困难。您的主要问题是您的登录页面必须了解有关用户登录的信息,但是登录会在弹出窗口中进行。您的弹出窗口都必须与主页进行通信,考虑到其中的一半发生在您绝对不允许与之通信的域上,这可能很难。如果这样做,则可以使用window.postMessage
。这也适用于页面本身上的iframe。另一个选项是,例如,定期检查localStorage,直到您的登录流返回带令牌或错误的信息为止。
具有oauth登录的SPA的最佳实践
我有一个Vue应用,我正在使用nodejs和MySQL作为后端。我想用Google,Facebook和本地登录来实现登录。
我花了数小时的时间阅读文档和教程,我很难把最好的方法和最佳实践结合起来。我尝试了很多可以成功登录的npm软件包,但是它们当然没有连接到服务器端,而从客户端(弹出窗口)发起请求时,服务器端库(例如passwordjs)似乎不能很好地发挥作用。至少我无法使其正常工作。
我希望登录可以在单独的窗口中进行,并且成功登录后用户将停留在同一页面上,并且页面状态得以保留。
有人知道我如何通过对后端的验证请求并尽可能简单地做到这一点〜100%安全吗?
谢谢
回答如下:免责声明:我只为公司系统实现了oauth流,该系统似乎总是以某种方式违反库中的流,因此习惯于手动实现这些流。这篇文章旨在让您掌握oauth的工作方式,发生的不同流程以及基本指南,以了解您在何处需要哪些信息。
据我所知,普通的Web应用程序通常使用三个Oauth流程,即:
- 使用授权码的流被交换为访问令牌]
- 直接返回访问令牌的流。
- 需要用户在您的网站上输入用户名和密码的流量,然后在您的后端将其交换为访问令牌
还有更多的oauth流程,但此处不相关。您可以阅读有关它们的更多信息on the website oauth。
对于具有自己的前端和后端的应用程序,授权代码是必经之路。对于仅具有前端且没有您控制的api的应用程序,仅具有访问令牌的流非常有用。第三种选择是有风险的,因为(例如)您要让人们在example上输入其Google凭据。您可以信守诺言,仅用此内容完成oauth流程...或者您不能假冒用户。前两个流程将登录过程与您要验证的站点分开,仅通过令牌共享访问权限。
让您的后端信任令牌
由于具有前端和后端,请选择将返回授权代码的流程。由于您在其他站点上输入凭据,因此经常涉及重定向。
- 您的应用从Oauth提供者打开一个页面,定义一个重定向URL。有时您定义两个,一个代表成功,一个代表失败。
- 用户在Oauth提供者的页面上输入其凭据
- Oauth提供者 生成授权令牌,并使用授权令牌重定向到重定向URL
要让您的后端信任用户就是他们声称的用户,您需要将授权令牌获取到您的后端。您可以通过输入直接指向您的api的重定向URL或输入指向您自己的应用程序的重定向url来实现,然后该应用程序将检索并将授权令牌传递给您的api。
验证特定用户
通常,您希望api中的用户概念与Oauth完全分开,这既是因为您不想在每次需要有关用户的信息时都必须查询Oauth提供程序,也因为它在实施新的Oauth提供程序或您自己的用户名/密码方案时,可以使您的生活更加轻松。这意味着,就您的Vue应用程序而言,仅当您的api表示对用户进行身份验证时,才对用户进行身份验证。当用户具有允许其发出api请求的Bearer令牌或cookie时,它知道用户已通过身份验证。您的Vue应用程序并不关心Bearer令牌或cookie的产生方式。
对于您的后端,您需要神奇地决定必须认证哪个用户。在上一节中,我们讨论了将授权令牌传递到后端的问题。无论您使用什么,都需要完成以下任务:
- 与Oauth提供者交换授权令牌以获取访问令牌。您可以通过从后端直接向oauth提供商进行http请求来做到这一点。 oauth提供者将使用访问令牌进行响应。您可以使用此访问令牌获取有关用户的信息。
- 使用具有访问令牌的Oauth提供程序进行调用以获取在数据库中找到正确用户所需的任何信息
- 如果找到了用户,则现在可以为该用户创建承载令牌或会话。如果找不到用户,则可以创建一个用户,提示用户创建一个用户或出错。
- 将不记名令牌或会话cookie返回到前端。如果您进行了api调用以传递授权令牌,那么该令牌将为您切出。如果您输入的是api网址作为重定向网址,则必须以某种方式传递此信息。可能最简单的方法是重定向到应用程序中的特定页面,该页面需要令牌并将其存储在某个位置。
使它与弹出窗口一起工作
通过弹出窗口完成所有这些工作比较困难。您的主要问题是您的登录页面必须了解有关用户登录的信息,但是登录会在弹出窗口中进行。您的弹出窗口都必须与主页进行通信,考虑到其中的一半发生在您绝对不允许与之通信的域上,这可能很难。如果这样做,则可以使用window.postMessage
。这也适用于页面本身上的iframe。另一个选项是,例如,定期检查localStorage,直到您的登录流返回带令牌或错误的信息为止。