因此,我正在使用slim/slim
和league/oauth2-server
开发 API 来管理 OAuth2 连接。 OAuth2很有用,因为我将需要在服务之间使用 Client Credentials授予。
然后,我还正在使用 React Native 开发一个混合应用程序。此应用程序将要求用户使用电子邮件和密码或与其他服务(例如Facebook,Google,Twitter等)连接来登录。
对于这种情况下要使用的OAuth2流,我感到困惑。网上有很多文章说资源所有者密码凭据不再安全,我们应该改用带有PKCE的身份验证代码。
但是我无法发现或理解如何在第一方应用程序中通过PKCE应用身份验证代码,因为所有有关您的文档都需要使用浏览器在redirect_uri
中获取身份验证代码。
我想象中的流程是这样的:
- 用户打开应用,然后插入您的凭据
username
和password
; - 此屏幕将连接到发送
/request_token
的API{ 'grant_type': 'password','username': username,'password': password,'client_id': CLIENT_ID }
URI,认为它是我们无法发送client_secret
的公共应用; - API会验证凭据并返回诸如
{ "access_token": access_token,"token_type": "JWT","expires_in": LIFE_SPAN }
之类的数据,这里我们将使用 JWT 来基于access_token
来使public/private key
脱颖而出; - 身份验证完成后,应用将在
access_token
处于活动状态时对其进行存储,并且当其到期时,将流向refresh_token
。
我的问题:安全吗? Scott Brady did some "aggressive" article talking it's NEVER safe。
这些应用如何进行?例如,当我使用Instagram应用程序时,他们拥有该应用程序和API,因此我不需要用户体验流程中的浏览器。现代应用程序是否使用“资源所有者密码凭据”或“带有PKCE的身份验证代码”?可以避免在使用“带有PKCE的身份验证代码”时在流程中插入浏览器吗?
[EDIT] 可能的解决方案
正如Gary Archer所说:“建议使用PKCE进行身份验证代码流-以及通过系统浏览器登录”,但我们并不是在谈论授予访问用户数据或第三方应用程序的权限。
作为设计师,我不同意由同一API所有者拥有的第一方应用程序中的登录要求使用浏览器,这不是我们想要的用户体验。还有我们看到的所有应用程序,例如Instagram,Facebook,Uber ...我们只需输入您的用户名和密码,即可访问您的帐户。
我要做的是使用PKCE创建一个自定义版本的身份验证代码,并删除了required_uri
。
[EDIT:2] 新流程
经过大量搜索,我发现了一些我认为很有趣的答案。如上所述,我从流程中删除了redirect_url
。看:
- 流程在用户提供您的凭据时从登录屏幕开始;
-
客户端生成一个
code_verifier
,然后将code_verifier
散列到code_challenge
,并使用以下参数将其发送到授权服务器:-
response_type=code
:表示您的服务器希望接收授权码。 -
client_id=xxxx
:客户端ID。 -
client_integrity=xxxx
:第一方应用的应用完整性检查。 -
code_challenge=xxxx
:如上所述生成的代码质询。 -
code_challenge_method=S256
:纯文本或S256,具体取决于质询是纯验证符字符串还是字符串的SHA256哈希。如果省略此参数,则服务器将采用普通格式。 -
username=xxxx
:要验证的用户名。 -
password=xxxx
:密码的哈希版本。 -
state=xxxx
:由您的应用程序生成的随机字符串(CSRF保护)。
-
-
授权服务器将验证用户身份验证,存储
code_challenge
并返回带有authorization_code
的{{1}}; -
客户端收到
client_token
和aauthorization_code
后,将保存client_token
,并立即使用以下参数将client_token
发送回授权服务器:-
authorization_code
:指定此令牌请求的授予类型。 -
grant_type=authorization_code
:客户端将发送它获得的授权代码。 -
code=xxxx
:客户端ID。 -
client_id=xxxx
:客户端最初在授权请求之前生成的PKCE请求的代码验证程序。
-
-
授权服务器将验证所有数据,如果一切正确,将返回
code_verifier=xxxx
; - 客户端将使用
access_token
设置授权标头,并始终向每个请求发送access_token
,只有两个值都正确时,才会接受它; - 如果
client_token
过期,则客户端将请求刷新access_token
并获取一个新请求。
现在,我将把这种逻辑重现为PHP语言。如果一切顺利,我希望一切顺利,我将以明确的答案回来。
[编辑] 说明
我正在使用 OAuth2 来连接您的第三方帐户(Google,Facebook等)。但是用户也可以登录到我的数据库中的本地帐户。在这种情况下,用户根本不需要授予任何权限。因此,将用户发送到浏览器对他进行登录没有任何意义。
在这种情况下,我想知道本地帐户是否可以使用资源所有者密码凭据,或者使用PKCE的身份验证代码更安全(我们已经得出结论,这是更好的选择Approuch)。但是带有PKCE的身份验证代码需要access_token
,我是否需要使用此重定向将用户登录到不需要授予访问权限的本地帐户?