简体   繁体   English

在 devise_token_auth 中成功 Oauth2 授权后如何将登录信息发送到前端?

[英]How to send sign in info to frontend after successful Oauth2 authorization in devise_token_auth?

I'm using devise_token_auth for Email and Google Oauth2 based authentication(used omniauth-google-oauth2 gem for this).我将devise_token_auth用于 Email 和基于 Google Oauth2 的身份验证(为此使用omniauth-google-oauth2 gem)。 I've successfully managed to store sign in info of the user signing up/in through Google Oauth2 flow.我已经成功地通过 Google Oauth2 流程存储了用户注册/登录的登录信息。 The info includes:信息包括:

{"auth_token"=>"token here", "client_id"=>"client id here", "uid"=>"uid here", "expiry"=>1620492005, "config"=>nil, "oauth_registration"=>true}

The flow for the above info was上述信息的流程是

  1. Visit http://localhost:3000/auth/google_oauth2.访问 http://localhost:3000/auth/google_oauth2。 This redirects you to the Google auth screen这会将您重定向到 Google 身份验证屏幕
  2. User selects account and grants permission.用户选择帐户并授予权限。
  3. Oauth success callback from my app is executed at http://localhost:3000/auth/google_oauth2/callback我的应用程序的 Oauth 成功回调在 http://localhost:3000/auth/google_oauth2/callback 执行

The code which executes for the first step is第一步执行的代码是

module DeviseTokenAuth
  class OmniauthCallbacksController < DeviseTokenAuth::ApplicationController
    attr_reader :auth_params

    before_action :validate_auth_origin_url_param
    
    def omniauth_success
      get_resource_from_auth_hash
      set_token_on_resource
      create_auth_params

      if confirmable_enabled?
        # don't send confirmation email!!!
        @resource.skip_confirmation!
      end

      sign_in(:user, @resource, store: false, bypass: false)

      @resource.save!

      yield @resource if block_given?

      render_data_or_redirect('deliverCredentials', @auth_params.as_json, @resource.as_json)
    end
  end
end

Problems I'm facing:我面临的问题:

  1. sign_in method call does not set @current_user despite that @resource and @auth_params have all the necessary info in them.尽管@resource@auth_params包含所有必要的信息,但sign_in方法调用并未设置@current_user
  2. How can I inform my frontend app about the sign in info(token, client_id, uid)?如何通知我的前端应用程序有关登录信息(令牌,client_id,uid)?
render_data_or_redirect('deliverCredentials', @auth_params.as_json, @resource.as_json)

this call does not redirect or render anything, instead it stays on the same page the URL it shows is http://localhost:3000/auth/google_oauth2/callback#此调用不会重定向或呈现任何内容,而是保持在同一页面上 URL 它显示为 http://localhost:3000/auth/google_oauth2/callback#

I basically have three questions now:我现在基本上有三个问题:

  1. How can I use devise_token_auth to set the current_user based on the incoming auth headers?如何使用devise_token_auth根据传入的身份验证标头设置current_user I have added the following line to my controller, but still it fails to set @current_user我在 controller 中添加了以下行,但仍然无法设置@current_user
include DeviseTokenAuth::Concerns::SetUserByToken

maybe it is because I'm sending auth headers incorrectly?也许是因为我错误地发送了身份验证标头? See my 3rd point below for this.请参阅下面的第三点。

  1. How am I supposed to send the sign in info to my frontend app?我应该如何将登录信息发送到我的前端应用程序? Do I modify the above method somehow to send sign in info to my frontend app?我是否以某种方式修改上述方法以将登录信息发送到我的前端应用程序?

  2. What and where do I put the auth headers in order to make authenticated requests?为了发出经过身份验证的请求,我应该在哪里放置 auth 标头?

  • When using devise_token_auth with email as auth provider I have to send 3 pieces to make an authenticated request ie access-token , client_id and uid当使用带有devise_token_auth作为身份验证提供程序的 devise_token_auth 时,我必须发送 3 件来发出经过身份验证的请求,即access-tokenclient_iduid
  • Now in case of providers like Google/Facebook etc, do I set all of these headers or not?现在,对于 Google/Facebook 等提供商,我是否设置所有这些标头?

I have used postman to test both of the following but it failed with Unauthorized error我已经使用 postman 来测试以下两个但它失败了未经授权的错误

  1. Sent access-token , client_id and uid in headers在 headers 中发送access-tokenclient_iduid
  2. Sent Bearer my_token in authorization headers.在授权标头中发送Bearer my_token

To get this working, we had to override the DeviseTokenAuth 's OmniAuthCallbacks controller and update its render_data_or_redirect method .为了让它工作,我们必须重写DeviseTokenAuthOmniAuthCallbacks controller 并更新它的render_data_or_redirect 方法

The default definition of render_data_or_redirect is render_data_or_redirect的默认定义是

def render_data_or_redirect(message, data, user_data = {})
  if ['inAppBrowser', 'newWindow'].include?(omniauth_window_type)
    render_data(message, user_data.merge(data))
  elsif auth_origin_url

    redirect_to DeviseTokenAuth::Url.generate(auth_origin_url, data.merge(blank: true))
  else
    fallback_render data[:error] || 'An error occurred'
  end
end

The following routes.rb and custom_omniauth_callbacks_controller.rb have the changes needed to be done to get it working with j-toker library.以下routes.rbcustom_omniauth_callbacks_controller.rb需要进行更改才能使其与j-toker库一起使用。

In the routes file在路由文件中

# config/routes.rb

mount_devise_token_auth_for 'User', at: 'auth', controllers: {
  omniauth_callbacks: "devise_token_auth/custom_omniauth_callbacks"
}

and the definition of CustomOmniAuthCallbacksController was CustomOmniAuthCallbacksController的定义是

# app/controllers/devise_token_auth/custom_omniauth_callbacks_controller.rb

module DeviseTokenAuth
  class CustomOmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController
    protected

    def render_data_or_redirect(message, data, user_data = {})
      if (['inAppBrowser', 'newWindow'].include?(omniauth_window_type) || auth_origin_url)

        redirect_to DeviseTokenAuth::Url.generate(auth_origin_url, data.merge(blank: true))
      else
        fallback_render data[:error] || 'An error occurred'
      end
    end
  end
end

now on the front-end side you need to configure j-toker现在在前端你需要配置j-toker

First, install j-toker package, yarn package or npm package一、安装j-toker package、纱线packagenpm ZEFE90A8E6034A7C840E8F8D

yarn add j-toker

or或者

npm i j-toker

then in your javascript application, configure the j-toker然后在您的 javascript 应用程序中,配置j-toker

import $ from "jquery";

$.auth.configure({
    apiUrl: "https://your-api-domain.com",
    emailSignInPath: "/auth/sign_in",
    signOutPath: "/auth/sign_out",
    emailRegistrationPath: "/auth",
    tokenValidationPath: "/auth/validate_token"

    authProviderPaths: {
      facebook: "/auth/facebook",
      google: "/auth/google_oauth2"
    }
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM