Omniauth返回401未经授权

时间:2014-02-13 18:40:26

标签: ruby-on-rails omniauth

我想在我的网站上实现登录并注册Twitter omniauth。我已关注this Railscast,但当我点击“使用Twitter登录”链接时,我收到了401 Unauthorized。当我查看日志时,我看到了:

GET "/users/auth/twitter/callback?oauth_token=xxx&oauth_verifier=xxx
omniauth: (twitter) Callback phase initiated.
Processing by OmniauthCallbacksController#twitter as HTML
  Parameters: {"oauth_token"=>"xxx", "oauth_verifier"=>"xxx"}
  User Load (1.3ms)  SELECT "users".* FROM "users" WHERE "users"."provider" = 'twitter' AND "users"."uid" = '9999' ORDER BY "users"."id" ASC LIMIT 1
   (0.3ms)  BEGIN
   (0.2ms)  COMMIT
Completed 401 Unauthorized in 13ms

当我查看omniauth控制器时,它找到了一个用户,但它似乎在sign_in_and_redirect user行上失败了。

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def all
    user = User.from_omniauth(request.env["omniauth.auth"])
    if user.persisted?
      # it reaches this
      flash.notice = I18n.t('.devise.omniauth_callbacks.success')
      sign_in_and_redirect user
    else
      session["devise.user_attributes"] = user.attributes
      redirect_to new_user_registration_url, notice: I18n.t('.devise.omniauth_callbacks.failure')
    end
  end
  alias_method :twitter, :all
end

config/devise.rb中我添加了这样的密钥和秘密:

config.omniauth :twitter, ENV.fetch("TWITTER_CONSUMER_KEY"), ENV.fetch("TWITTER_CONSUMER_SECRET")

然后实际值存储在.rvmrc中,如下所示:

export TWITTER_CONSUMER_KEY=xxx
export TWITTER_CONSUMER_SECRET=xxx

这可能意味着它尝试登录找到的用户但是在某些验证失败了吗?但我删除了用户模型中的所有验证,以检查发生了什么,我仍然收到此错误。任何人都知道这里可能有什么问题吗?

2 个答案:

答案 0 :(得分:1)

我有同样的问题(&#34; Omniauth返回401未经授权的#34;)但原因不同。

在我的User#from_omniauth我这样做

where(provider: auth.provider, uid: auth.uid).first_or_create

这意味着它创建了一个新用户(如果还没有用户)。此外,我的Userdevise :confirmable,未经证实的用户无法登录。这就是身份验证失败的原因。

会有一条错误消息说明这一点,但在视图中我被重定向到没有:

<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

因此,解决方案是将其添加到CallbacksController中的方法:

def github
  @user = User.from_omniauth(request.env['omniauth.auth'])

  if @user.persisted?
    @user.skip_confirmation!
    @user.save
  #...

skip_confirmation是一种设计方法,它在用户上执行此操作:

self.confirmed_at = Time.now.utc

所以,或者这可以在User.from_omniauth

中完成

答案 1 :(得分:0)

问题应该是strong parameters。我建议你从request.env["omniauth.auth"]得到一些变量,而不是直接用于创建或查找。

def self.from_omniauth(auth)
 uid = auth[:uid]
 provider = auth[:provider]

 User.where(provider: provider, uid: uid).first
end

这应该可以解决未经授权的错误。