[英]devise_token_auth omniauth JSON response?
我有一個Rails 5站點,它由2部分組成:
我在兩個部分使用Devise,為API前端使用https://github.com/lynndylanhurley/devise_token_auth gem。
問題是關於使用omniauth身份驗證。 當omniauth對管理區域進行身份驗證時 - 一切正常 - 我得到了一些成功的HTML響應。
但問題是我在API領域得到了相同的HTML響應 - 但我需要一些JSON響應 - 而不是HTML響應。
這是我的代碼:
配置/ 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
應用程序/模型/ 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
應用程序/控制器/用戶/ 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
配置/初始化/ 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
的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"}
我猜這個問題是關於一個所謂的“回調”網址。 我不明白它的位置。 從日志中可以明顯看出,在auth過程結束時, GET "/omniauth/vkontakte/callback..."
了GET "/omniauth/vkontakte/callback..."
查詢。 並且可能它總是被調用 - 無論我是從admin還是api客戶區發起誓序。
我使用Chrome Postman進行API查詢http://localhost:3000/api/auth/vkontakte
- 我得到了HTML -response(“成功登錄等”) - 但我肯定需要一些JSON響應。
有沒有辦法根據一些前提條件動態更改回調路徑? 回調查詢是否有所不同,具體取決於啟動誓言程序的位置?
EDIT1:
不幸的是,這不是一個單一的問題。 看起來oauth根本沒有在https://github.com/lynndylanhurley/devise_token_auth gem中實現。 因此,即使我成功將oauth登錄過程切換為JSON方式 - 如何以devise_token_auth-way方式登錄用戶 - 生成3個令牌等...? app / controllers / users / omniauth_callbacks_controller.rb需要完全重新發布。
您可以根據從API請求連接時提供的一些額外參數,從OmniauthCallbacksController
渲染json。 這些額外參數將在此哈希request.env["omniauth.params"]
可用。
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def vkontakte
@user = User.from_omniauth_vkontakte(request.env["omniauth.auth"])
if @user.persisted?
sign_in @user, :event => :authentication #this will throw if @user is not activated
set_flash_message(:notice, :success, :kind => "Vkontakte") if is_navigational_format?
if request.env["omniauth.params"]["apiRequest"]
render status: 200, json: { message: "Login success" }
else
redirect_to after_sign_in_path_for(@user)
end
else
session["devise.vkontakte_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
您可以通過使用其他參數調用auth helper來獲取這些額外的參數,它們將被傳遞給您的OmniauthController: user_vkontakte_omniauth_authorize_path(api_request: true)
(或者您的路徑助手是什么)
我最終實現了自己的oauth回調過程 - 而不是使用devise_token_auth
gem中的一個。
devise_token_auth
gem確實包含oauth身份驗證 - 但它似乎無法正常工作。
這是我的代碼更改:
配置/ 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'}
end
end
應用程序/控制器/用戶/ omniauth_callbacks_controller.rb
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
include DeviseTokenAuth::Concerns::SetUserByToken
5個auth標頭作為響應:
access-token →BeX35KJfYVheKifFdwMPag
client →96a_7jXewCThas3mpe-NhA
expiry →1499340863
token-type →Bearer
uid →376449571
但響應仍然缺少這些標頭(可在常見的登錄中使用):
Access-Control-Allow-Credentials →true
Access-Control-Allow-Methods →GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin →chrome-extension://aicmkgpgakddgnaphhhpliifpcfhicfo
Access-Control-Max-Age →1728000
我不知道它們是否重要,如果是的話 - 如何提供它們。
PS同樣的方法也適用於Facebook。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.