这是我实现这种登录/注册逻辑的计划(授权代码流程) . ( The third-party only provided the OAuth2 API )
首先,SPA前端将向第三方发送GET请求
GET https://www.example.com/oauth2
client_id=dummyclient
redirect_uri=https://mysite/callback
response_type=code
scope=openid
然后,如果用户同意将他/她的openid提供给mysite,那么fronend将获得301 HTTP响应 .
---> 301 https://mysite/callback?code=dummycode
然后浏览器将页面重定向到 mysite/callback
,它将重新加载SPA并在URL中公开可以由SPA捕获的代码,然后它将代码发送到真正的后端回调 .
GET https://mysite/api/real-callback?code=dummycode
当后端获取代码时,它会将代码发送给第三方以交换 access_token
. 当后端获得 access_token
时,它将触发API请求以获取用户的openid,然后决定是让用户登录还是注册为新用户 . 最后,它将向我们的SPA前端返回一个HTTP响应,其中包含 my OAuth2系统中的 access_token
或401未经授权的响应 .
所以我的问题是如何证明真正的回调是由 my 自己的客户端调用的(因为如果一些攻击者得到我的前端嵌入 client_id
那么他可以伪造OAuth2请求并钓鱼用户同意 . 之后攻击者将得到一个有效的代码然后他将代码发送回我的真实回调 . 最后,他将在我的系统中获得用户的 access_token
. )如何在没有最终用户提供密码等附加信息的情况下使用OAuth2进行身份验证 .
1 回答
我建议你将OAuth2流程更改为Implicit,同时要求
access_token
和id_token
(OpenID Connect) . 您的SPA将获得令牌,将ID令牌发送到您的后端,后端可以使用它来决定是否可以创建此类用户 . SPA可以使用访问令牌来调用受保护的资源 .这条路,
只有SPA才是OAuth2客户端 - 两个应用程序(SPA和后端)不会使用令牌,
你只有一个重定向URI,
您不需要将令牌从后端转移到SPA .
Update: Without OpenID Connect
如果您不能使用
id_token
,您可以将access_token
发送到您的后端,后端可以通过向令牌发送到Introspection endpoints https://tools.ietf.org/html/rfc7662(来自响应username
属性)来获取用户的用户名 .username
属性是可选的 . 您的OAuth2服务器可能会返回更多信息(例如姓名和电子邮件) .此内省 endpoints 需要身份验证,因此要使用它,您的后端必须是具有自己的
client_id
和秘密的已注册OAuth2客户端 .