0

我試圖做一個認證的路線/me使用omniauth-google-oauth2。到目前爲止,我已經建立了登錄和註銷庫,並且工作正常。不過,我希望只有當用戶登錄時才能訪問某些路線。我發現this snippet並做了一些小修改以適應我的設置。Omniauth認證的路線谷歌

application_controller.rb

before_filter :authenticate 
def authenticate 
    redirect_to :login unless User.from_omniauth(env["omniauth.auth"]) 
end 

user.rb

def self.from_omniauth(auth) 
    where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user| 
     user.provider = auth.provider 
     user.uid = auth.uid 
     user.name = auth.info.name 
     user.first_name = auth.info.first_name 
     user.last_name = auth.info.last_name 
     user.email = auth.info.email 
     user.picture = auth.info.image 
     user.oauth_token = auth.credentials.token 
     user.oauth_expires_at = Time.at(auth.credentials.expires_at) 
     user.save! 
    end 

我以前env["omniauth"],因爲這是我在SessionsController使用的身份驗證哈希。

不過,現在每當我去localhost:3000,我得到以下錯誤:

undefined method `provider' for nil:NilClass 

我假設這是因爲env["omniauth.auth"]是不是從application_controller.rb訪問?如果是這樣的話,那麼我該如何正確訪問認證哈希?

+1

你的'from_omniauth'類方法在'user.rb'文件中看起來像什麼? –

+0

@JustinLicata剛剛更新了原來的文章 – Carpetfizz

+1

'env [「omniauth.auth」]'當您訪問「localhost:3000」時返回'nil'。我相信的原因是這個env變量只能在社交登錄後的回調請求中設置。對於所有其他請求,這將是'nil'。 –

回答

1

試試這個:

application_controller.rb

before_filter :authenticate 

def authenticate 
    redirect_to :login unless user_signed_in? 
end 

def user_signed_in? 
    !!current_user 
end 

def current_user 
    @current_user ||= begin 
    User.find(session[:current_user_id]) || fetch_user_from_omniauth 
    end 
end 

def fetch_user_from_omniauth 
    user = User.from_omniauth(env['omniauth.auth']) 
    session[:current_user_id] = user.id 
    user 
end 

這將首先嚐試獲取已登錄的用戶(從會話)。如果沒有找到,它會嘗試從omniauth創建一個用戶,然後在session中設置它的id,這樣對於下一個請求,它不需要env中的omniauth來查找當前用戶。

+0

謝謝,我想了解你的答案。你爲什麼在'social_controller.rb'中跳過驗證,以及這個控制器的角色是什麼?這是否與創建會話的相同? – Carpetfizz

+0

順便說一句,我的Sessions.rb是認證回調是 – Carpetfizz

+0

我修改了它,請現在檢查。 –