Devise + Omniauth + Carrierwave 不保存 facebook/github 个人资料图片
Devise + Omniauth + Carrierwave doesn't save facebook/github profile image
之前我只使用 Omni auth + devise 来让用户注册。一切正常。后来我决定使用简单的注册形式设计。我配置了它,它也工作正常,但是当用户想要使用 Omni 身份验证注册时,问题就出现了。即使 facebook/Github 将 link 返回到个人资料图片,头像始终设置为 nil。我试过这个 solution 但是,仍然没有用,我知道载波远程位置上传方法。我用于 Omni 身份验证的 Gem 是 omniauth-facebook 和 omniauth-github.
(1)
User.rb
代码:
class User < ApplicationRecord
include Storext.model
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable, :validatable
validates :first_name, :last_name, :email, :experience_level,
:goal_level, :theoretical_learner_level, presence: true
mount_uploader :avatar, AvatarUploader
# Override devise method for Oauth
def self.new_with_session(params, session)
if session['devise.user_attributes']
new(session['devise.user_attributes'].merge(session[:user_attributes])) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid).to_hash).first_or_create do |user|
OauthUserGenerator.new(user: user, auth: auth).generate
end
end
# If sign in through Oauth, don't require password
def password_required?
super && provider.blank?
end
# Don't require update with password if Oauth
def update_with_password(params, *options)
if encrypted_password.blank?
update_attributes(params, *options)
else
super
end
end
end
(2)
oauth_user_generator.rb
代码:
class OauthUserGenerator
def initialize(user:, auth:)
@user = user
@auth = auth
end
def generate
@user.provider = @auth.provider
@user.uid = @auth.uid
@user.email = @auth.info.email
@user.password = Devise.friendly_token[0, 20]
@user.first_name = @auth.info.name.split[0]
@user.last_name = @auth.info.name.split[1]
@user.remote_avatar_url = @auth.info.image
end
end
(3)
omniauth_callbacks_controller.rb
代码:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def omniauth_providers
process_oauth(request.env['omniauth.auth'].merge(session.fetch(:user_attributes, {})))
end
alias facebook omniauth_providers
alias github omniauth_providers
private
def process_oauth(omniauth_params)
user = User.from_omniauth(omniauth_params)
if user.persisted?
flash.notice = 'Signed in!'
sign_in_and_redirect user
else
session['devise.user_attributes'] = user.attributes
redirect_to new_user_email_registration_path
end
end
end
谢谢。
前段时间我遇到了类似的问题。
显然,carrierwave 不允许 remote_url
从一个协议重定向到另一个协议。你用 auth.info.image
得到的 url 是一个 http
url,它重定向到 https
url。因此,在您的 OauthUserGenerator
class 中,在您的 generate
方法中。尝试执行以下操作:
@user.remote_avatar_url = @auth.info.image.gsub('http', 'https')
这样重定向将来自 https -> https
。那对我有用。希望这对你来说也是同样的问题。
之前我只使用 Omni auth + devise 来让用户注册。一切正常。后来我决定使用简单的注册形式设计。我配置了它,它也工作正常,但是当用户想要使用 Omni 身份验证注册时,问题就出现了。即使 facebook/Github 将 link 返回到个人资料图片,头像始终设置为 nil。我试过这个 solution 但是,仍然没有用,我知道载波远程位置上传方法。我用于 Omni 身份验证的 Gem 是 omniauth-facebook 和 omniauth-github.
(1)
User.rb
代码:
class User < ApplicationRecord
include Storext.model
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable, :validatable
validates :first_name, :last_name, :email, :experience_level,
:goal_level, :theoretical_learner_level, presence: true
mount_uploader :avatar, AvatarUploader
# Override devise method for Oauth
def self.new_with_session(params, session)
if session['devise.user_attributes']
new(session['devise.user_attributes'].merge(session[:user_attributes])) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid).to_hash).first_or_create do |user|
OauthUserGenerator.new(user: user, auth: auth).generate
end
end
# If sign in through Oauth, don't require password
def password_required?
super && provider.blank?
end
# Don't require update with password if Oauth
def update_with_password(params, *options)
if encrypted_password.blank?
update_attributes(params, *options)
else
super
end
end
end
(2)
oauth_user_generator.rb
代码:
class OauthUserGenerator
def initialize(user:, auth:)
@user = user
@auth = auth
end
def generate
@user.provider = @auth.provider
@user.uid = @auth.uid
@user.email = @auth.info.email
@user.password = Devise.friendly_token[0, 20]
@user.first_name = @auth.info.name.split[0]
@user.last_name = @auth.info.name.split[1]
@user.remote_avatar_url = @auth.info.image
end
end
(3)
omniauth_callbacks_controller.rb
代码:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def omniauth_providers
process_oauth(request.env['omniauth.auth'].merge(session.fetch(:user_attributes, {})))
end
alias facebook omniauth_providers
alias github omniauth_providers
private
def process_oauth(omniauth_params)
user = User.from_omniauth(omniauth_params)
if user.persisted?
flash.notice = 'Signed in!'
sign_in_and_redirect user
else
session['devise.user_attributes'] = user.attributes
redirect_to new_user_email_registration_path
end
end
end
谢谢。
前段时间我遇到了类似的问题。
显然,carrierwave 不允许 remote_url
从一个协议重定向到另一个协议。你用 auth.info.image
得到的 url 是一个 http
url,它重定向到 https
url。因此,在您的 OauthUserGenerator
class 中,在您的 generate
方法中。尝试执行以下操作:
@user.remote_avatar_url = @auth.info.image.gsub('http', 'https')
这样重定向将来自 https -> https
。那对我有用。希望这对你来说也是同样的问题。