从 oauth 登录将 JWT 令牌返回到 javascript SPA

Posted

技术标签:

【中文标题】从 oauth 登录将 JWT 令牌返回到 javascript SPA【英文标题】:Return JWT token to javascript SPA from oauth login 【发布时间】:2017-10-18 17:57:12 【问题描述】:

我正在 vue.js 中开发一个 javascript spa,它最终将成为一个 cordova 应用程序。以及一个用 lumen 构建的后端 api。

我正在尝试使用 facebook 和 google 功能提供登录。我添加了 laravel socialite 包并创建了重定向和回调路由。我已经在我的 spa 中创建了一个页面,其中包含指向我的 api 重定向的登录按钮。用户被重定向到我登录的 facebook 的 oauth 机制,回调路由句柄函数看起来像这样

public function handleProviderCallback($provider)

  $oauthUser = $this->socialiteManager->with($provider)->stateless()->user();

  $userEntity = $this->repository->findOrCreateOauthUser($oauthUser);

  $providerEntity = app()
    ->make('em')
    ->getRepository('Entities\Social\Provider')
    ->findOneBy(['name' => $provider]);

  if(is_null($providerEntity))
  
    throw new \Exception('Oauth Provider not found');
  

  $socialAccountEntity = app()
    ->make('em')
    ->getRepository('Entities\Social\SocialAccount')
    ->findOrCreateSocialAccount($providerEntity, $oauthUser, $userEntity);  

  $token = $this->auth->fromUser($userEntity);

  $resource = $this->item($token)
      ->transformWith($this->transformer)
      ->serializeWith(new ArraySerialization())
      ->toArray();

  return $this->showResponse($resource);

它基本上是获取一个 oauth 用户,在数据库中查找或存储他们,查找或存储他们的社交帐户信息,

$token = $this->auth->fromUser($userEntity);

然后使用发布令牌的 JWT 对它们进行身份验证。然后将其序列化并作为 json 响应返回。

问题是在后端应用程序上给出了响应,我从未返回到 javascript SPA。

我可以做一些重定向而不是返回 json,比如

return redirect()->to('/some-spa-callback-route');

但是 api 是否应该知道 SPA 位置?当 SPA 被移植到 cordova 时,这将如何工作,因为移动应用程序没有 url?

我的想法是A

社交提供者应该直接重定向到 SPA,此时它应该发出另一个请求,将授权代码交换为 JWT 令牌。

B 它使用包含令牌的查询字符串重定向到 SPA,这听起来不安全。

或 c 发回某种类型的 cookie。

我仍然对如何从我的 api 实际重定向到移动应用程序感到困惑。

【问题讨论】:

【参考方案1】:

您的水疗中心不应处理 2 个服务,而应与后端中的单个身份验证服务通信。您将您的服务注册为 oauth 回调,并按照您的描述处理 oauth/jwt。您的身份验证服务也可以是用户(重新)身份验证的决策点。由于您的前端直接调用您的后端,您现在可以将 json 有效负载返回给您的网络/移动调用者。

【讨论】:

这并没有解决当您在 api 回调时如何将用户引导回 SPA 的问题【参考方案2】:

最后我得到了以下登录流程

用户被定向到 Oauth 提供者 Oauth 提供者向客户端返回访问令牌 客户端将访问令牌发送到我的 api 我的 api 向 Oauth 提供者发送更新请求 Oauth 提供者验证令牌并向我的 api 返回一个新令牌 我的 api 将访问令牌交换为 jwt 令牌 我的 api 将 jwt 令牌返回给客户端

在我看来,这是对 SPA 应用程序进行身份验证的唯一正确方法,重要的是更新客户端提供的 Oauth 令牌,而不是盲目地交换 jwt,因为您无法信任客户端,并且比发布更好从不太稳定的 api 重定向

【讨论】:

我认为更新访问令牌没有必要或有益。您提到不信任客户端,但这正是令牌交换的目的以及访问令牌的寿命很短的事实。通过更新访问令牌,这是否意味着您延长了请求的生命周期,从而增加了安全风险? 谢谢。我有完全相同的问题。由于某种原因,网上没有教程,从头到尾描述这个过程。 @user618509,我使用与您相同的技术堆栈。我设法在社交身份验证后获得了 access_token。但问题是。您是如何将 access_token 发送给您的客户的?我使用的是 laravel/passport 而不是 jwt tho。

以上是关于从 oauth 登录将 JWT 令牌返回到 javascript SPA的主要内容,如果未能解决你的问题,请参考以下文章

如何基于使用 Oauth2 协议的身份验证改进 JWT 访问令牌和刷新令牌?

OAuth授权后如何向客户端发送jwt令牌?

REST API 的安全认证,从 OAuth 2.0 到 JWT 令牌

是否可以在 JWT 中包含 OAuth 范围?

单点登录JWT与Spring Security OAuth

OAuth 2.0 与 JWT