使用pkce的单页应用程序的现代oauth

本文探讨了OAuth规范的发展,强调了在单页应用程序(SPA)中使用PKCE的重要性。PKCE解决了OAuth隐式流的安全问题,提供了一种更安全的身份验证方式。通过授权码与PKCE流程,前端可以直接安全地获取访问令牌,提高用户体验。
摘要由CSDN通过智能技术生成

The OAuth specification was first published in 2007. Today’s web development landscape, dominated by Single Page Applications (SPAs) built on frameworks such as React and Angular, would have been completely alien to the committee that created the first draft of OAuth. Recall that this was a time when MySpace was one of the largest websites around and mobile apps as we know them today did not exist.

OAuth规范于2007年首次发布。如今的Web开发环境,以在React和Angular等框架上构建的单页应用程序(SPA)为主,对创建OAuth初稿的委员会来说是完全陌生的。 回想一下,这是MySpace成为周围最大的网站和移动应用程序之一的时代,我们知道今天它们不存在。

It is no surprise then that OAuth has gone through several revisions. The first major revision was the launch of OAuth 2.0 in 2012, which catered for some of the glaring omissions previously mentioned. However, software development is a rapidly moving field and even the norms and technologies widely used in 2012 for development have largely been replaced today.

毫不奇怪,OAuth经历了多次修订。 第一个主要修订版本是OAuth 2.0于2012年发布,该版本解决了前面提到的一些明显的遗漏。 但是,软件开发是一个快速发展的领域,甚至2012年广泛用于开发的规范和技术也已在今天被替换。

This story will focus on how OAuth has been updated to reflect the needs of today’s web applications powered by SPA frameworks and how we can use these new functionalities to write secure code that interacts with third party APIs.

本故事将重点介绍如何更新OAuth以反映当今由SPA框架提供支持的Web应用程序的需求,以及我们如何使用这些新功能来编写与第三方API交互的安全代码。

OAuth流101: (OAuth Flows 101:)

OAuth has several “flows” through which developers can allow users to let them access their data from another application. Almost every flow involves the user passing their credentials directly to the external API and an access token being received by your app which then represents the authenticated user. Let’s quickly study the four main OAuth flows before continuing our discussion.

OAuth具有多个“流”,开发人员可以通过它们使用户允许他们从另一个应用程序访问其数据。 几乎每个流程都涉及用户将其凭据直接传递到外部API,以及您的应用程序接收的访问令牌,然后访问令牌代表经过身份验证的用户。 在继续讨论之前,让我们快速研究四个主要的OAuth流程。

  1. Implicit Flow: This is probably the most famous and widely used OAuth flow. In this flow, the user is presented a dialog box to enter their credentials for the external API (say Facebook or Google). After entering their credentials, they are redirected to a route with the access token conveniently placed in the URL as a query parameter. This method is commonly used with web apps without a backend server. No client secret is involved.

    隐式流:这可能是最著名和使用最广泛的OAuth流。 在此流程中,向用户显示一个对话框,以输入其外部API(例如Facebook或Google)的凭据。 输入凭据后,会将它们重定向到带有方便放置在URL中的访问令牌作为查询参数的路由。 此方法通常用于不具有后端服务器的Web应用程序。 不涉及任何客户机密。

Image for post
Typical Implicit Flow Process
典型的隐式流程

2. Authorization Code: This is the alternative to implicit flow and is commonly used when there is a backend server connected to the web app. In this flow, the user enters their credentials as usual, but instead of directly returning the token as in implicit flow, the OAuth provider instead returns a code. This code, along with the client secret, is sent in another POST request to the auth provider to get the key. This method cannot be used with just a web front-end app because it requires a client secret which you should never expose to your web client.

2.授权代码:这是隐式流程的替代方法,通常在有后端服务器连接到Web应用程序时使用。 在此流程中,用户照常输入其凭据,但是OAuth提供程序不是像隐式流程那样直接返回令牌,而是返回代码。 此代码以及客户端机密在另一个POST请求中发送给auth提供程序以获取密钥。 此方法不能仅与Web前端应用程序一起使用,因为它需要一个客户端机密,您绝不能向Web客户端公开该机密。

Image for post
Typical Authorization Code Flow
典型授权码流程

3. Client Credentials: This is a less commonly used flow. No user is involved in this flow. Instead, the your backend server directly authenticates with the OAuth server to get a token. The major limitation of this method is that you cannot get the access token of a specific user and are only limited to accessing publicly available information within the external API.

3.客户凭证:这是一种不太常用的流程。 没有用户参与此流程。 相反,您的后端服务器直接向OAuth服务器进行身份验证以获取令牌。 此方法的主要限制是您无法获取特定用户的访问令牌,而只能访问外部API中的公开信息。

4. Authorization Code with Proof Key for Code Exchange PKCE: Authorization Code with PKCE (pronounced ‘pixy’) can be thought of as a combination of Implicit Flow and Authorization Code flow. It allows the authorization code flow to be used directly on the web client, as it eliminates the need for a client secret by using a hash challenge to verify the client as follows:

4.带有用于密钥交换 PKCE的 证明密钥的授权代码:带有PKCE的授权代码(发音为“ pixy”)可以被认为是隐式流程和授权代码流程的组合。 它允许授权代码流直接在Web客户端上使用,因为它通过使用散列质询来验证客户端,从而消除了对客户端机密的需求,如下所示:

Image for post

Here, the code verifier is a random string. It is different each time the front-end app gets loaded. The server verifies that the request in part 3 of the above diagram is coming from the same origin as the request in part 1 by calculating the hash of the code verifier itself in part 3 which should then be the same as the hash received in part 1.

此处,代码验证程序是随机字符串。 每次加载前端应用程序时都会有所不同。 服务器通过计算第3部分中代码验证程序本身的哈希值(该哈希值应与第1部分中接收的哈希值相同)来验证上图第3部分中的请求与第1部分中的请求来自同一来源。

PKCE的隐式流与授权码 (Implicit Flow vs Authorization Code with PKCE)

TLDR: Implicit Flow is an archaic standard with security vulnerabilities. Use Authorization Code with PKCE wherever possible instead of Implicit Flow.

TLDR:隐式流是具有安全漏洞的古老标准。 尽可能在PKCE中使用授权代码,而不要使用隐式流程。

Implicit flow and Authorization code flow with PKCE are both viable approaches for authenticating directly on an SPA client, as they both ultimately ensure that your client app ends up with the OAuth access token. However, Implicit Flow returns the access token as part of the URL, which is a major security vulnerability as anyone who can see the URL of the redirect can impersonate the user. Authorization code flow solves this problem by returning the token securely in the response body of a POST request. Therefore you should always aim to use the Authorization Code flow with PKCE instead of the Implicit Flow.

PKCE的隐式流和授权码流都是直接在SPA客户端上进行身份验证的可行方法,因为它们最终都可以确保您的客户端应用最终获得OAuth访问令牌。 但是,Implicit Flow将访问令牌作为URL的一部分返回,这是一个主要的安全漏洞,因为任何看到重定向URL的人都可以冒充用户。 授权代码流通过在POST请求的响应正文中安全地返回令牌来解决此问题。 因此,您应该始终旨在将授权代码流与PKCE结合使用,而不是隐式流。

授权码与带有PKCE的授权码 (Authorization Code vs Authorization Code with PKCE)

This is a common dilemma that people face when they have an SPA client such as React connected to their own back-end. In this case you can either use the Authorization Code flow to retrieve the token on your backend server or use the Authorization Code with PKCE flow to retrieve your token at the front-end. Which one should you use? Unless you have a good reason to absolutely require the token to be retrieved on the server side, I would recommend you still go with the Authorization Code with PKCE.

当人们将诸如React之类的SPA客户端连接到自己的后端时,这是一个普遍的难题。 在这种情况下,您既可以使用授权码流程在后端服务器上检索令牌,也可以使用带有PKCE的授权码流程在前端检索令牌。 您应该使用哪一个? 除非有充分的理由绝对要求在服务器端检索令牌,否则我建议您仍然使用带有PKCE的授权码。

This is because using the Authorization Code flow leaves the user hanging on the front-end, as the redirect is to the server. Suppose we have a client-side rendered React app with a Node/Express backend and we are implementing a login with a third party provider. Refer to the authorization code flow (without PKCE) diagram above. When the OAuth provider returns the access code in step 4 to the back-end, at that point your user on the web app will still be on the login screen and the server will have no way to communicate to the server that the authentication was successful. The web app will have to be refreshed at this point to be updated.

这是因为使用授权代码流会使用户挂在前端,因为重定向到服务器。 假设我们有一个带有Node / Express后端的客户端渲染React应用,并且我们正在实现与第三方提供商的登录。 请参考上面的授权码流程(无PKCE)图。 当OAuth提供者将步骤4中的访问代码返回到后端时,此时您在Web应用程序上的用户仍将在登录屏幕上,并且服务器将无法与服务器通信,验证成功。 此刻必须刷新Web应用程序才能进行更新。

In contrast, the PKCE flow resolves on the web app, which allows us to send the token to the backend server and immediately update the display on the web app once we get the response. This results in a much smoother user experience.

相反,PKCE流程在Web应用程序上解析,这使我们能够将令牌发送到后端服务器,并在获得响应后立即更新Web应用程序上的显示。 这样可以带来更加流畅的用户体验。

示例:使用Spotify的API通过PKCE实现OAuth (Example: Implementing OAuth with PKCE using Spotify’s API)

Let’s do a quick example to see the Auth Code with PKCE flow in action. We’ll use a barebones React app. We will implement a single functionality in our app that allows the user to login to Spotify to get an access token. We’ll pretend to send this access token to our backend and which will use it to register the user in our database by extracting the email from the token.

让我们做一个简单的示例,看看使用PKCE流的身份验证代码。 我们将使用准系统React应用程序。 我们将在我们的应用程序中实现一个功能,该功能允许用户登录到Spotify以获得访问令牌。 我们将假装将此访问令牌发送到我们的后端,然后它将通过从令牌中提取电子邮件来使用它在数据库中注册用户。

Spotify’s API implements the PKCE authorization flow and has easy to follow documentation which you can follow.

Spotify的API实现了PKCE授权流程,并且具有易于遵循的文档,您可以按照以下文档进行操作

First, here is our main App.jsx file. Our app only has two components: one to initiate the login flow and the other to handle the redirect from step 2 in the PKCE flow diagram above.

首先,这是我们的主要App.jsx文件。 我们的应用程序仅包含两个组件:一个用于启动登录流程,另一个用于处理上述PKCE流程图中步骤2的重定向。

Next up is the Login component. Upon clicking the login button, a random string of random length is generated. The base-64 encoded hash of this is calculated and included in the URL redirect where the user enters their details to be sent to the Spotify server. Another random string, called the state, is generated and sent in the request. This can be checked later to verify that the response from Spotify is legitimate. The code verifier and state are stored in local storage, since we will need them in the next step when we handle the redirect from the Spotify API.

接下来是Login组件。 单击登录按钮后,将生成一个随机长度的随机字符串。 计算此值的基数为64的哈希,并将其包含在URL重定向中,用户在其中输入要发送到Spotify服务器的详细信息。 另一个随机字符串(称为状态)在请求中生成并发送。 以后可以检查以确认来自Spotify的响应是合法的。 代码验证程序和状态存储在本地存储中,因为在处理来自Spotify API的重定向时,下一步将需要它们。

Finally, we have a component to handle the redirect from the Spotify API. The redirect includes a code which we can use to generate an access token through a POST request. However, we cannot just use the code to exchange for the token. We will also need to include the unhashed code verifier we generated and stored in the last step. Here, we also verify the state we sent in the previous part.

最后,我们有一个组件来处理来自Spotify API的重定向。 重定向包含一个代码,我们可以使用该代码通过POST请求生成访问令牌。 但是,我们不能仅仅使用代码来交换令牌。 我们还需要包括在最后一步中生成并存储的完整的代码验证程序。 在这里,我们还验证了上一部分中发送的状态。

Once we have the token, we can send it to our backend server which can use the token to extract the user’s email and other details and store them in the database.

获得令牌后,我们可以将其发送到后端服务器,后端服务器可以使用令牌提取用户的电子邮件和其他详细信息,并将其存储在数据库中。

结语 (Wrapping up)

OAuth has evolved significantly over the years. The Authorization Code with PKCE flow is one of the latest additions that is designed to be used with Single Page Applications built on frameworks such React, Angular or Vue. The PKCE flow overcomes the issues and vulnerabilities of the old Implicit Flow and is the recommended method to receive OAuth tokens in modern web apps. Spotify provides a well-documented authorization API which you can use to learn how to implement the PKCE flow.

多年来,OAuth有了长足的发展。 具有PKCE流程的授权码是最新添加的功能之一,旨在与基于React,Angular或Vue等框架构建的Single Page Applications一起使用。 PKCE流克服了旧的隐式流的问题和漏洞,是在现代Web应用程序中接收OAuth令牌的推荐方法。 Spotify提供了一个文档齐全的授权API,您可以使用它来学习如何实现PKCE流程。

翻译自: https://medium.com/swlh/modern-oauth-for-single-page-applications-using-pkce-e1cdd2f1b84

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值