【发布时间】:2017-11-23 05:48:02
【问题描述】:
我有一个 Rails 5 站点,它由两部分组成:
- 管理区
- 仅限 API 的客户区
我将 Devise 用于这两个部分,https://github.com/lynndylanhurley/devise_token_auth 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
app/models/user.rb
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
app/controllers/users/omniauth_callbacks_controller.rb
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
config/initializers/devise.rb
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
宝石文件
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"}
我猜问题出在所谓的“回调”网址上。我不明白它在哪里设置。从日志中可以明显看出,在身份验证过程结束时调用了GET "/omniauth/vkontakte/callback..." 查询。并且它可能总是被调用 - 无论我是从管理员还是 api 客户端区域启动誓言序列。
我使用 Chrome Postman 进行 API 查询 http://localhost:3000/api/auth/vkontakte - 我得到了 HTML - 响应(“成功登录等”) - 但我肯定需要一些 JSON-响应。
有没有办法根据某些前提条件动态更改回调路径? 回调查询是否因宣誓程序的启动位置而有所不同?
EDIT1:
不幸的是,这不是一个单一的问题。看起来 oauth 根本没有在 https://github.com/lynndylanhurley/devise_token_auth gem 中实现。所以,即使我成功地将 oauth 登录过程切换到 JSON 方式 - 我如何登录用户 devise_token_auth 方式 - 生成 3 个令牌等......? app/controllers/users/omniauth_callbacks_controller.rb 需要完全重新实现。
【问题讨论】:
标签: ruby-on-rails json devise