Ruby on rails 设计令牌认证omniauth JSON响应?

Ruby on rails 设计令牌认证omniauth JSON响应?,ruby-on-rails,json,devise,Ruby On Rails,Json,Devise,我有一个Rails 5站点,它由两部分组成: 行政区 仅API客户端区域 我使用Desive作为部件,使用gem作为API前端 问题在于使用omniauth身份验证。当我在管理区进行omniauth身份验证时——一切正常——我得到了一些成功的HTML响应 但问题是,我在API区域得到了相同的HTML响应——但我需要一些JSON响应——而不是HTML响应 这是我的密码: config/routes.rb Rails.application.routes.draw do devise_fo

我有一个Rails 5站点,它由两部分组成:

  • 行政区
  • 仅API客户端区域
  • 我使用Desive作为部件,使用gem作为API前端

    问题在于使用omniauth身份验证。当我在管理区进行omniauth身份验证时——一切正常——我得到了一些成功的HTML响应

    但问题是,我在API区域得到了相同的HTML响应——但我需要一些JSON响应——而不是HTML响应

    这是我的密码:

    config/routes.rb

    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions', :omniauth_callbacks => 'api/users/omniauth_callbacks' }    
    
        end
    end
    
    class User < ApplicationRecord
    
      # Include default devise modules.
      devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable,
              :omniauthable,
              :omniauth_providers => [:facebook, :vkontakte]
    
      include DeviseTokenAuth::Concerns::User
    
      devise :omniauthable
    
      def self.from_omniauth_vkontakte(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
          user.email = auth.extra.raw_info.first_name.to_s + "." + auth.extra.raw_info.last_name.to_s + '@vk.com'      
          user.password = Devise.friendly_token[0,20]
        end
      end
    
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        if @user.persisted?
          sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
          set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    Devise.setup do |config|
    
      config.omniauth :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"], provider_ignores_state: true
    
      config.omniauth :vkontakte, ENV["VKONTAKTE_APP_ID"], ENV["VKONTAKTE_APP_SECRET"]
    
    end
    
    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions'}   
    
        end
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      include DeviseTokenAuth::Concerns::SetUserByToken
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        namespace_name = request.env["omniauth.params"]["namespace_name"]
    
        if @user.persisted?
    
          if namespace_name && namespace_name == "api"
    
            @client_id = SecureRandom.urlsafe_base64(nil, false)
            @token     = SecureRandom.urlsafe_base64(nil, false)
    
            @user.tokens[@client_id] = {
              token: BCrypt::Password.create(@token),
              expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
            }
            @user.save
    
            @resource = @user # trade-off for "update_auth_header" defined in "DeviseTokenAuth::Concerns::SetUserByToken"
    
            sign_in(:user, @user, store: false, bypass: false)        
    
            render json: @user
    
          else
    
            sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
            set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
    
          end
    
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    app/models/user.rb

    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions', :omniauth_callbacks => 'api/users/omniauth_callbacks' }    
    
        end
    end
    
    class User < ApplicationRecord
    
      # Include default devise modules.
      devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable,
              :omniauthable,
              :omniauth_providers => [:facebook, :vkontakte]
    
      include DeviseTokenAuth::Concerns::User
    
      devise :omniauthable
    
      def self.from_omniauth_vkontakte(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
          user.email = auth.extra.raw_info.first_name.to_s + "." + auth.extra.raw_info.last_name.to_s + '@vk.com'      
          user.password = Devise.friendly_token[0,20]
        end
      end
    
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        if @user.persisted?
          sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
          set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    Devise.setup do |config|
    
      config.omniauth :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"], provider_ignores_state: true
    
      config.omniauth :vkontakte, ENV["VKONTAKTE_APP_ID"], ENV["VKONTAKTE_APP_SECRET"]
    
    end
    
    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions'}   
    
        end
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      include DeviseTokenAuth::Concerns::SetUserByToken
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        namespace_name = request.env["omniauth.params"]["namespace_name"]
    
        if @user.persisted?
    
          if namespace_name && namespace_name == "api"
    
            @client_id = SecureRandom.urlsafe_base64(nil, false)
            @token     = SecureRandom.urlsafe_base64(nil, false)
    
            @user.tokens[@client_id] = {
              token: BCrypt::Password.create(@token),
              expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
            }
            @user.save
    
            @resource = @user # trade-off for "update_auth_header" defined in "DeviseTokenAuth::Concerns::SetUserByToken"
    
            sign_in(:user, @user, store: false, bypass: false)        
    
            render json: @user
    
          else
    
            sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
            set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
    
          end
    
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    Gemfile

    gem 'omniauth'
    gem 'omniauth-facebook'
    gem 'omniauth-vkontakte'
    
    Gemfile.lock

    devise (4.3.0)
    devise_token_auth (0.1.42)
    
    这是我的日志:

    Started GET "/api/auth/vkontakte" for 127.0.0.1 at 2017-06-20 17:34:23
    +0300 
    Started GET "/omniauth/vkontakte?namespace_name=api&resource_class=User" for
    127.0.0.1 at 2017-06-20 17:34:23 +0300 
    I, [2017-06-20T17:34:23.237270 #15747]  INFO -- omniauth: (vkontakte) Request phase initiated. 
    Started GET "/omniauth/vkontakte/callback?code=0b8446c5fe6873bb12&state=52254649eb899e3b743779a1a4afc0304f249a6dd90b4415" for 127.0.0.1 at 2017-06-20 17:34:23 +0300 
    I, [2017-06-20T17:34:23.672200 #15747]  INFO -- omniauth: (vkontakte) Callback phase initiated. Processing by Users::OmniauthCallbacksController#vkontakte as */*   Parameters: {"code"=>"0b8446c5fe6873bb12", "state"=>"52254649eb899e3b743779a1a4afc0304f249a6dd90b4415"}
    
    我想问题在于所谓的“回调”url。我不明白放在哪里。从日志中可以明显看出,在身份验证过程结束时,将调用
    GET”/omniauth/vkontakte/callback…
    查询。而且它可能总是被调用——不管我是从admin还是api客户端启动宣誓序列

    我使用Chrome Postman进行API查询
    http://localhost:3000/api/auth/vkontakte
    -我得到了HTML-响应(“成功登录等”)-但我确实需要一些JSON-响应

    有没有办法根据某个前提条件动态更改回调路径? 回调查询是否与启动宣誓过程的位置有所不同

    EDIT1:


    不幸的是,这不是一个单一的问题。看起来oauth根本没有在gem中实现。因此,即使我成功地将oauth登录过程切换到JSON方式-我如何登录用户designe_token_auth-way-生成3个令牌等等。。。?app/controllers/users/omniauth\u callbacks\u controller.rb需要完全重新配置。

    例如,当您从API请求连接时,可以根据提供的一些额外参数从
    omniauth callbackcontroller
    呈现json。 这些额外参数将在此哈希
    request.env[“omniauth.params”]
    中可用

    class Users::OmniAuthCallbackController:authentication#如果未激活@user,将引发此错误
    如果是导航格式,则设置flash消息(:notice,:success,:kind=>“Vkontakte”)?
    if request.env[“omniauth.params”][“apirest”]
    呈现状态:200,json:{message:“登录成功”}
    其他的
    重定向到(@user)的路径中的签名后
    结束
    其他的
    会话[“designe.vkontakte_data”]=request.env[“omniauth.auth”]
    将\重定向到新\用户\注册\ url
    结束
    结束
    结束
    

    您可以通过使用其他参数调用auth帮助器来创建这些额外参数,这些参数将传递给您的OmniauthController:
    用户\u vkontakte\u omniauth\u授权\u路径(api\u请求:true)
    (或任何路由帮助器)

    例如,当您从API请求连接时,可以根据提供的一些额外参数从
    OmniAuthCallbackController
    呈现json。 这些额外参数将在此哈希
    request.env[“omniauth.params”]
    中可用

    class Users::OmniAuthCallbackController:authentication#如果未激活@user,将引发此错误
    如果是导航格式,则设置flash消息(:notice,:success,:kind=>“Vkontakte”)?
    if request.env[“omniauth.params”][“apirest”]
    呈现状态:200,json:{message:“登录成功”}
    其他的
    重定向到(@user)的路径中的签名后
    结束
    其他的
    会话[“designe.vkontakte_data”]=request.env[“omniauth.auth”]
    将\重定向到新\用户\注册\ url
    结束
    结束
    结束
    

    您可以通过使用其他参数调用auth帮助器来创建这些额外参数,这些参数将传递给您的OmniauthController:
    用户\u vkontakte\u omniauth\u授权\u路径(api\u请求:true)
    (或任何路由帮助器)

    我最终实现了自己的oauth回调过程,而不是使用
    designe\u token\u auth
    gem中的回调过程

    designe\u token\u auth
    gem确实包含oauth身份验证,但它似乎工作不正常

    以下是我的代码更改:

    config/routes.rb

    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions', :omniauth_callbacks => 'api/users/omniauth_callbacks' }    
    
        end
    end
    
    class User < ApplicationRecord
    
      # Include default devise modules.
      devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable,
              :omniauthable,
              :omniauth_providers => [:facebook, :vkontakte]
    
      include DeviseTokenAuth::Concerns::User
    
      devise :omniauthable
    
      def self.from_omniauth_vkontakte(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
          user.email = auth.extra.raw_info.first_name.to_s + "." + auth.extra.raw_info.last_name.to_s + '@vk.com'      
          user.password = Devise.friendly_token[0,20]
        end
      end
    
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        if @user.persisted?
          sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
          set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    Devise.setup do |config|
    
      config.omniauth :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"], provider_ignores_state: true
    
      config.omniauth :vkontakte, ENV["VKONTAKTE_APP_ID"], ENV["VKONTAKTE_APP_SECRET"]
    
    end
    
    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions'}   
    
        end
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      include DeviseTokenAuth::Concerns::SetUserByToken
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        namespace_name = request.env["omniauth.params"]["namespace_name"]
    
        if @user.persisted?
    
          if namespace_name && namespace_name == "api"
    
            @client_id = SecureRandom.urlsafe_base64(nil, false)
            @token     = SecureRandom.urlsafe_base64(nil, false)
    
            @user.tokens[@client_id] = {
              token: BCrypt::Password.create(@token),
              expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
            }
            @user.save
    
            @resource = @user # trade-off for "update_auth_header" defined in "DeviseTokenAuth::Concerns::SetUserByToken"
    
            sign_in(:user, @user, store: false, bypass: false)        
    
            render json: @user
    
          else
    
            sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
            set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
    
          end
    
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    app/controllers/users/omniauth\u callbacks\u controller.rb

    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions', :omniauth_callbacks => 'api/users/omniauth_callbacks' }    
    
        end
    end
    
    class User < ApplicationRecord
    
      # Include default devise modules.
      devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable,
              :omniauthable,
              :omniauth_providers => [:facebook, :vkontakte]
    
      include DeviseTokenAuth::Concerns::User
    
      devise :omniauthable
    
      def self.from_omniauth_vkontakte(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
          user.email = auth.extra.raw_info.first_name.to_s + "." + auth.extra.raw_info.last_name.to_s + '@vk.com'      
          user.password = Devise.friendly_token[0,20]
        end
      end
    
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        if @user.persisted?
          sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
          set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    Devise.setup do |config|
    
      config.omniauth :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"], provider_ignores_state: true
    
      config.omniauth :vkontakte, ENV["VKONTAKTE_APP_ID"], ENV["VKONTAKTE_APP_SECRET"]
    
    end
    
    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions'}   
    
        end
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      include DeviseTokenAuth::Concerns::SetUserByToken
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        namespace_name = request.env["omniauth.params"]["namespace_name"]
    
        if @user.persisted?
    
          if namespace_name && namespace_name == "api"
    
            @client_id = SecureRandom.urlsafe_base64(nil, false)
            @token     = SecureRandom.urlsafe_base64(nil, false)
    
            @user.tokens[@client_id] = {
              token: BCrypt::Password.create(@token),
              expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
            }
            @user.save
    
            @resource = @user # trade-off for "update_auth_header" defined in "DeviseTokenAuth::Concerns::SetUserByToken"
    
            sign_in(:user, @user, store: false, bypass: false)        
    
            render json: @user
    
          else
    
            sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
            set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
    
          end
    
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    但响应仍然缺少以下标题(可在公共登录处获得):

    我不知道它们是否重要,如果重要,如何提供它们


    PS同样的方法也适用于Facebook。

    我最终实现了自己的oauth回调过程,而不是使用来自
    designe\u token\u auth
    gem的回调过程

    designe\u token\u auth
    gem确实包含oauth身份验证,但它似乎工作不正常

    以下是我的代码更改:

    config/routes.rb

    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions', :omniauth_callbacks => 'api/users/omniauth_callbacks' }    
    
        end
    end
    
    class User < ApplicationRecord
    
      # Include default devise modules.
      devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable,
              :omniauthable,
              :omniauth_providers => [:facebook, :vkontakte]
    
      include DeviseTokenAuth::Concerns::User
    
      devise :omniauthable
    
      def self.from_omniauth_vkontakte(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
          user.email = auth.extra.raw_info.first_name.to_s + "." + auth.extra.raw_info.last_name.to_s + '@vk.com'      
          user.password = Devise.friendly_token[0,20]
        end
      end
    
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        if @user.persisted?
          sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
          set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    Devise.setup do |config|
    
      config.omniauth :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"], provider_ignores_state: true
    
      config.omniauth :vkontakte, ENV["VKONTAKTE_APP_ID"], ENV["VKONTAKTE_APP_SECRET"]
    
    end
    
    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions'}   
    
        end
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      include DeviseTokenAuth::Concerns::SetUserByToken
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        namespace_name = request.env["omniauth.params"]["namespace_name"]
    
        if @user.persisted?
    
          if namespace_name && namespace_name == "api"
    
            @client_id = SecureRandom.urlsafe_base64(nil, false)
            @token     = SecureRandom.urlsafe_base64(nil, false)
    
            @user.tokens[@client_id] = {
              token: BCrypt::Password.create(@token),
              expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
            }
            @user.save
    
            @resource = @user # trade-off for "update_auth_header" defined in "DeviseTokenAuth::Concerns::SetUserByToken"
    
            sign_in(:user, @user, store: false, bypass: false)        
    
            render json: @user
    
          else
    
            sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
            set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
    
          end
    
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    app/controllers/users/omniauth\u callbacks\u controller.rb

    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions', :omniauth_callbacks => 'api/users/omniauth_callbacks' }    
    
        end
    end
    
    class User < ApplicationRecord
    
      # Include default devise modules.
      devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable,
              :omniauthable,
              :omniauth_providers => [:facebook, :vkontakte]
    
      include DeviseTokenAuth::Concerns::User
    
      devise :omniauthable
    
      def self.from_omniauth_vkontakte(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
          user.email = auth.extra.raw_info.first_name.to_s + "." + auth.extra.raw_info.last_name.to_s + '@vk.com'      
          user.password = Devise.friendly_token[0,20]
        end
      end
    
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        if @user.persisted?
          sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
          set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    Devise.setup do |config|
    
      config.omniauth :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"], provider_ignores_state: true
    
      config.omniauth :vkontakte, ENV["VKONTAKTE_APP_ID"], ENV["VKONTAKTE_APP_SECRET"]
    
    end
    
    Rails.application.routes.draw do
    
        devise_for :users, controllers: { sessions: 'users/sessions', :omniauth_callbacks => 'users/omniauth_callbacks' }
    
        namespace :api do   
    
            mount_devise_token_auth_for 'User', at: 'auth', controllers: { sessions: 'api/users/sessions'}   
    
        end
    end
    
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      include DeviseTokenAuth::Concerns::SetUserByToken
    
      def vkontakte
        @user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
    
        namespace_name = request.env["omniauth.params"]["namespace_name"]
    
        if @user.persisted?
    
          if namespace_name && namespace_name == "api"
    
            @client_id = SecureRandom.urlsafe_base64(nil, false)
            @token     = SecureRandom.urlsafe_base64(nil, false)
    
            @user.tokens[@client_id] = {
              token: BCrypt::Password.create(@token),
              expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
            }
            @user.save
    
            @resource = @user # trade-off for "update_auth_header" defined in "DeviseTokenAuth::Concerns::SetUserByToken"
    
            sign_in(:user, @user, store: false, bypass: false)        
    
            render json: @user
    
          else
    
            sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
            set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
    
          end
    
        else
          session["devise.vkontakte_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end    
      end
    
    end
    
    但响应仍然缺少以下标题(可在公共登录处获得):

    我不知道它们是否重要,如果重要,如何提供它们


    PS同样的方法也适用于Facebook。

    我试图
    http://localhost:3000/api/auth/vkontakte?api=true
    ,但运气不好。远程服务器没有使用此新参数调用我的回调。我犯了一个小错误,其他参数将在这里可用
    request.env[“omniauth.params”][“api_request”]
    ,我已更新了我的应答是的,这一个是doe