问题描述
我试图(再次)使用Rails 4,devise和omniauth设置身份验证。我试图按照这篇文章中的示例:
我安装了这些宝石:
gem'devise'
gem'omniauth- google-oauth2'
gem'omniauth-facebook'
gem'omniauth-twitter'
gem'omniauth-linkedin-oauth2'
gem'oauth2'
我有一个用户模型和一个身份验证模型。
I有:
User.rb:
has_many:authentications
def disapprove
self.approved = false
end
def approve
self.approved = true
end
SOCIALS = {
Facebook:'Facebook',
google_oauth2:'G oogle',
linkedin:'Linkedin'
}
def self.from_omniauth(auth,current_user)
authentication = Authentication.where(:provider => auth.provider,
:uid => auth.uid.to_s,
:token => auth.credentials.token,
:secret => auth.credentials.secret).first_or_initialize
authentication.profile_page = auth.info.urls.first.last除非authentication.persisted?
如果authentication.user.blank?
user = current_user.nil? ? User.where('email =?',auth ['info'] ['email'])。first:current_user
如果user.blank?
user = User.new
user.skip_confirmation!
user.password = Devise.friendly_token [0,20]
user.fetch_details(auth)
user.save
end
authentication.user = user
authentication.save
end
authentication.user
end
def fetch_details(auth)
self.first_name = auth.info.first_name
self.last_name = auth.info.last_name
self.email = auth.info.email
self.image = URI.parse(auth.info.image)
end
Authentication.rb
belongs_to:user
Routes.rb
devise_for:users,
:controllers => {
:registrations => 用户/注册,
:omniauth_callbacks => 'users / omniauth_callbacks',
}
用户/ registrations_controller
class Users :: RegistrationsController< Devise :: RegistrationsController
#before_filter:check_permissions,:only => [:new,:create,,cancel]
#skip_before_filter:require_no_authentication
def check_permissions
授权! :create,resource
end
def index
如果params [:approved] ==false
@users = User.find_all_by_approved(false)
else
@users = User.all
end
end
def create
@user = User.new(user_params)#(params [:用户])
respond_to do | format |
如果resource.save
#在保存
#{@user.send_admin_mail
#@ user.send_user_welcome_mail}之后,告诉UserMailer发送欢迎电子邮件
format.html {redirect_to(profile_path(@ user.profile))}
#,注意:我们已收到您的注册。我们将很快联系''}
#format.json {render json:root_path,status::created,location:@user}
else
#format.html {redirect_to root_path,alert:'对不起,你的注册有问题,请联系我们来整理出来。'}}
format.html {render action:'new'}
format.json {render json:@ user.errors,status::unprocessable_entity}
end
end
end
private
def user_params
params.require( :user).permit(:first_name,:last_name,:email,,password)
end
#protected
#def after_sign_up_path_for )
#'订阅者/新'
#end
end
User / Omniauth_callbacks controller
class Users :: OmniauthCallbacksController< Devise :: OmniauthCallbacksController
#再试一次http://stackoverflow.com/questions/21249749/rails-4-devise- omniauth-with-multiple-providers
def all
user = User.from_omniauth(env ['omniauth.auth'],current_user)
如果user.persisted?
sign_in user
flash [:notice] = t('devise.omniauth_callbacks.success',:kind => User :: SOCIALS [params [:action] .to_sym])
if user.sign_in_count == 1
redirect_to profile_path(@ user.profile)
else
redirect_to root_path
end
else
session ['devise.user_attributes' ] = user.attributes
redirect_to root_path
end
end
用户:: SOCIALS.each do | k,_ |
alias_method k,:all
end
end
/新注册视图说:
<%= simple_form_for(resource,as:resource_name,url:registration_path(resource_name))do | F | %GT;
< div class =row>
< div class =col-md-3 col-md-offset-3>
< div class =row>
< div class =col-md-12>
<% - 如果devise_mapping.omniauthable? %GT;
< div class =facebookauth>
<%= link_to加入Facebook,user_omniauth_authorize_path(:facebook)%>
< / div>
<%end - %>
< / div>
< / div>
< div class =row>
< div class =col-md-12>
<% - if devise_mapping.omniauthable? %GT;
< div class =googleauth>
<%= link_to加入Google,user_omniauth_authorize_path(:google_oauth2)%>
< / div>
<%end - %>
< / div>
< / div>
< div class =row>
< div class =col-md-12>
<% - 如果devise_mapping.omniauthable? %GT;
< div class =linkedinauth>
<%= link_to加入LinkedIn,user_omniauth_authorize_path(:linkedin)%>
< / div>
<%end - %>
< / div>
< / div>
< div class =row>
< div class =col-md-12>
<% - 如果devise_mapping.omniauthable? %GT;
< div class =twitterauth>
<%= link_to加入Twitter,user_omniauth_authorize_path(:twitter)%>
< / div>
<%end - %>
< / div>
< / div>
< / div>
< div class =col-md-5>
< div class =emailform>
< div class =form-inputs,style =margin-left:7%>
<%= devise_error_messages! %GT;
<%= f.input:first_name,:label_html => {:class => 'deviselabels'},autofocus:true,required:false,:input_html => {:maxlength => 15,:size => 40,class:'lineitemdevise'}%>
<%= f.input:last_name,:label_html => {:class => 'deviselabels'},required:false,:input_html => {:maxlength => 15,:size => 40,class:'lineitemdevise'}%>
<%= f.input:email,:label_html => {:class => 'deviselabels'},required:false,autofocus:false,placeholder:请使用你的工作或大学地址,:input_html => {:maxlength => 55,:size => 40,class:'lineitemdevise'}%>
<%= f.input:password,:label_html => {:class => 'deviselabels'},required:false,占位符:最少8个字符,:input_html => {:maxlength => 15,:size => 40,class:'lineitemdevise'}%>
< / div>
< div class =form-actions>
<%= f.button:submit,通过电子邮件加入,class => dcpb%>
< / div>
<%end%>
< / div>
< / div>
我有另一个模型叫做profile.rb。
个人资料belongs_to用户
问题:
- 这些都不行。当我点击每个社交媒体登录链接时,页面只是通过电子邮件形式跳转到注册。
英雄日志错误消息说:
(facebook)认证失败! invalid_credentials:OAuth2 ::错误,:
2015-11-03T07:05:48.237549 + 00:00 app [web.1]:{error:{message:验证验证码错误请确定您的redirect_uri与OAuth对话框请求中使用的一样,type:OAuthException,code:100,fbtrace_id:HD3mnzmSTEw}}
- 当我用电子邮件和密码通过电子邮件表单完成注册时,用户名为认识到(导航栏说你好,但是当我进入导轨控制台时,用户没有列出。
另外,我点击用户名,我收到一个错误,表示该配置文件不存在。英雄日志说:
(Couldn 'id'= 3)
- 让社交媒体注册工作需要创建新用户的另一步骤?
我的下一个脚本:
我已经改变了上述的,然后再次尝试使用Railscasts视频中的方法。
我现在使用用户模型和身份验证模型。
在user.rb中,我有:
has_many:authentications,:dependent => :delete_all
def apply_omniauth(omniauth)
authentications.build(:provider => omniauth ['provider'],:uid => omniauth ['uid'],:token = &a)auth ['credentials'] ['token'])
end
authentication.rb
belongs_to:user
def self.from_omniauth(auth)
其中(auth.slice(:provider,:uid))。first_or_create do |用户|
authentication.provider = auth.provider
authentication.uid = auth.uid
authentication.user.first_name = auth.first_name
authentication.user.last_name = auth.last_name
authentication.user.image = auth.info.image
end
end
Authentications_controller:
class AuthenticationsController< ApplicationController
before_action:set_authentication,只有:[:destroy]
def index
@authentications = current_user.authentications如果current_user
end
def create
omniauth = request.env [omniauth.auth]
authentication = Authentication.find_by_provider_and_uid(omniauth ['provider'],omniauth ['uid'])
如果验证
sign_in_and_redirect_user(:user,authentication.user.profile)
elsif current_user
current_user.authentications.create!(:provider => omniauth ['provider'], :uid => omniauth ['uid'])
redirect_to user.profile_url
else
user = User.new
user.omniauth(omniauth)
如果用户。保存!
sign_in_and_redirect_user(:user,user.profile)
else
会话[:omniauth] = omniauth.except('extra')
redirect_to new_user_registration_url
end
end
end
def destroy
@ authentication.destroy
respond_to do | format |
format.html {redirect_to authentications_url}
format.json {head:no_content}
end
end
private
#使用回调共享动作之间的共同设置或约束。
def set_authentication
@authentication = current_user.authentications.find(params [:id])
end
end
在routes.rb中,我有:
devise_for:users ,
:controllers => {
:registrations => 用户/注册,
}
patch'/ auth /:provider / callback'=> '认证#创建'
Omniauth.rb
require'omniauth-facebook'
require'omniauth-google-oauth2'
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth :: Builder do
提供者:facebook,ENV ['FACEBOOK_ID'],ENV [' FACEBOOK_KEY'],
:scope => 'public_profile',info_fields:'id,first_name,last_name,link,email',
:display => 'popup',
:client_options => {:ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}}
然后当我尝试这个,我得到这个错误:
(facebook)身份验证失败! invalid_credentials:OAuth2 :: Error,,
/ pre>
2015-11-05T06:4839 + 00:00 app [web.1]:{error:{message:验证码验证错误请确保您的redirect_uri与OAuth对话框请求中使用的一样,type:OAuthException,code:100,fbtrace_id:CrvXN22Z}}
我发现错误信息的下一部分奇怪,因为它引用了我不再使用的回调控制器(整个事情被注释掉,没有路由)
认证失败! invalid_credentials:OAuth2 ::错误,:
2015-11-05T08:24:16.010951 + 00:00应用程序[web.1]:处理由Devise :: OmniauthCallbacksController#failed as HTML
2015-11- 05T08:24:16.012648 + 00:00 app [web.1]:重定向到http://www.dder.com/users/sign_in
进一步的尝试
我一直在努力设置超过1.5年的设计。这是我最新的尝试(遵循sitepoint.com/rails-authentication-oauth-2-0-omniauth的Sitepoint教程)。我以前试过使用这个教程,没有任何成功,所以我做了一些调整,尝试并适应这个主题的其他教程的一些方面。
我现在有:
user.rb
has_many:认证,依赖=> :delete_all
def apply_omniauth(omniauth)
authentications.build(:provider => omniauth ['provider'],:uid => omniauth ['uid'],:token = &a)auth ['credentials'] ['token'])
end
authentication.rb
belongs_to:user
def self.from_omniauth(auth)
其中(auth .slice(:provider,:uid))。first_or_create do |用户|
authentication.provider = auth.provider
authentication.uid = auth.uid
authentication.user.first_name = auth.first_name
authentication.user.last_name = auth.last_name
authentication.user.image = auth.info.image
end
end
认证控制器
class AuthenticationsController< Devise :: OmniauthCallbacksController
before_action:set_authentication,only:[:destroy]
def index
@authentications = current_user.authentications if current_user
end
def create
omniauth = request.env [omniauth.auth]
authentication = Authentication.find_by_provider_and_uid(omniauth ['provider'],omniauth ['uid'])
如果身份验证
sign_in_and_redirect_user(:user,authentication.user.profile)
elsif current_user
current_user.authentications.create!(:provider => omniauth ['provider '],:uid => omniauth ['uid'])
redirect_to user.profile_url
else
user = User.new
user.omniauth(omniauth)
如果user.save!
sign_in_and_redirect_user(:user,user.profile)
else
会话[:omniauth] = omniauth.except('extra')
redirect_to new_user_registration_url
end
end
end
def destroy
@ authentication.destroy
respond_to do | format |
format.html {redirect_to authentications_url}
format.json {head:no_content}
end
end
private
#使用回调共享动作之间的共同设置或约束。
def set_authentication
@authentication = current_user.authentications.find(params [:id])
end
end
注册控制器
class Users :: RegistrationsController< Devise :: RegistrationsController
#before_filter:check_permissions,:only => [:new,:create,,cancel]
#skip_before_filter:require_no_authentication
#before_action:configure_permitted_parameters,如果::devise_controller? #Sitepoint的建议教程 - 目前尚未实现,因为不能确定此设置和设置参数之间的区别。
def check_permissions
授权! :create,resource
end
def index
如果params [:approved] ==false
@users = User.find_all_by_approved(false)
else
@users = User.all
end
end
def create
super
session [:omniauth] = nil unless @ user.new_record?
end
#这是一个来自SITEPOINT TUTORIAL的建议
#protected
#def configure_permitted_parameters
#devise_parameter_sanitizer.for(:sign_up) << [:first_name,:last_name]
#end
private
def user_params
params.require(:user).permit(:first_name, last_name,:email,:password)
end
def build_resource(* args)
super
如果会话[:omniauth]
@ user.apply_omniauth (session [:omniauth])
@ user.valid?
end
end
end
/ p>
devise_for:users,
:controllers => {
:registrations => users / registrations,
:omniauth_callbacks => authentications
#:omniauth_callbacks => 'users / omniauth_callbacks',
}
get'/ auth /:provider / callback'=> '认证#创建'
我可以通过以下方式查看这些路线:
rake routes | grep auth
pre>
user_omniauth_authorize GET | POST /users/auth/:provider(.:format)authentications#passthru {:provider => / facebook | linkedin | twitter | google_oauth2 /}
user_omniauth_callback GET | POST /用户/ auth /:action / callback(。:format)认证#:action
GET /auth/:provider/callback(.:format)认证#create
新注册部分在视图
<% - 如果devise_mapping.omniauthable? %GT;
< div class =twitterauth>
<%= link_to加入Twitter,user_omniauth_authorize_path(:twitter)%>
< / div>
<%end - %>
我真的不知道这个路径是从哪里来的。不知道为什么它被命名为。
新会话部分在视图中
<% - 如果devise_mapping.omniauthable? %GT;
< div class =twitterauth>
<%= link_to使用Twitter登录,user_omniauth_authorize_path(:twitter)%>
< / div>
<%end - %>
当前错误:
AbstractController :: ActionNotFound at / users / auth / twitter / callback
找不到AuthenticationsController
解决方案Devise带有一个开箱即用的解决方案,用于与全方位集成。您可以结帐这些网址:
1.
这一个显示与DigitalOcean的整合,但可以扩展到其他人。
2.
这一个来自devise wiki
希望它有帮助
I am trying (again) to set up authentications with Rails 4, devise and omniauth.
I tried to follow the example in this post: Rails 4, Devise, Omniauth (with multiple providers)
I have these gems installed:
gem 'devise' gem 'omniauth-google-oauth2' gem 'omniauth-facebook' gem 'omniauth-twitter' gem 'omniauth-linkedin-oauth2' gem 'oauth2'
I have a user model, and an authentications model.
I have:
User.rb:
has_many :authentications def disapprove self.approved = false end def approve self.approved = true end
SOCIALS = { facebook: 'Facebook', google_oauth2: 'Google', linkedin: 'Linkedin' }
def self.from_omniauth(auth, current_user) authentication = Authentication.where(:provider => auth.provider, :uid => auth.uid.to_s, :token => auth.credentials.token, :secret => auth.credentials.secret).first_or_initialize authentication.profile_page = auth.info.urls.first.last unless authentication.persisted? if authentication.user.blank? user = current_user.nil? ? User.where('email = ?', auth['info']['email']).first : current_user if user.blank? user = User.new user.skip_confirmation! user.password = Devise.friendly_token[0, 20] user.fetch_details(auth) user.save end authentication.user = user authentication.save end authentication.user end def fetch_details(auth) self.first_name = auth.info.first_name self.last_name = auth.info.last_name self.email = auth.info.email self.image = URI.parse(auth.info.image) end
Authentication.rb
belongs_to :user
Routes.rb
devise_for :users, :controllers => { :registrations => "users/registrations", :omniauth_callbacks => 'users/omniauth_callbacks', }
User/registrations_controller
class Users::RegistrationsController < Devise::RegistrationsController #before_filter :check_permissions , :only => [ :new, :create, :cancel ] #skip_before_filter :require_no_authentication def check_permissions authorize! :create, resource end def index if params[:approved] == "false" @users = User.find_all_by_approved(false) else @users = User.all end end def create @user = User.new(user_params) #(params[:user]) respond_to do |format| if resource.save # Tell the UserMailer to send a welcome email after save # {@user.send_admin_mail # @user.send_user_welcome_mail} format.html { redirect_to(profile_path(@user.profile))} #, notice: 'We have received your registration. We will be in touch shortly.') } #format.json { render json: root_path, status: :created, location: @user } else #format.html { redirect_to(root_path, alert: 'Sorry! There was a problem with your registration. Please contact us to sort it out.') } format.html { render action: 'new' } format.json { render json: @user.errors, status: :unprocessable_entity } end end end private def user_params params.require(:user).permit(:first_name, :last_name, :email, :password ) end # protected # def after_sign_up_path_for(resource) # 'subscribers/new' # end end
User/Omniauth_callbacks controller
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
# try again following http://stackoverflow.com/questions/21249749/rails-4-devise-omniauth-with-multiple-providers def all user = User.from_omniauth(env['omniauth.auth'], current_user) if user.persisted? sign_in user flash[:notice] = t('devise.omniauth_callbacks.success', :kind => User::SOCIALS[params[:action].to_sym]) if user.sign_in_count == 1 redirect_to profile_path(@user.profile) else redirect_to root_path end else session['devise.user_attributes'] = user.attributes redirect_to root_path end end User::SOCIALS.each do |k, _| alias_method k, :all end end
The devise/new registrations view says:
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <div class="row"> <div class="col-md-3 col-md-offset-3"> <div class="row"> <div class="col-md-12"> <%- if devise_mapping.omniauthable? %> <div class="facebookauth"> <%= link_to "Join with Facebook", user_omniauth_authorize_path(:facebook) %> </div> <% end -%> </div> </div> <div class="row"> <div class="col-md-12"> <%- if devise_mapping.omniauthable? %> <div class="googleauth"> <%= link_to "Join with Google", user_omniauth_authorize_path(:google_oauth2) %> </div> <% end -%> </div> </div> <div class="row"> <div class="col-md-12"> <%- if devise_mapping.omniauthable? %> <div class="linkedinauth"> <%= link_to "Join with LinkedIn", user_omniauth_authorize_path(:linkedin) %> </div> <% end -%> </div> </div> <div class="row"> <div class="col-md-12"> <%- if devise_mapping.omniauthable? %> <div class="twitterauth"> <%= link_to "Join with Twitter", user_omniauth_authorize_path(:twitter) %> </div> <% end -%> </div> </div> </div> <div class="col-md-5"> <div class="emailform"> <div class="form-inputs", style="margin-left: 7%"> <%= devise_error_messages! %> <%= f.input :first_name, :label_html => {:class => 'deviselabels'}, autofocus: true, required: false, :input_html => {:maxlength => 15, :size => 40, class: 'lineitemdevise'} %> <%= f.input :last_name, :label_html => {:class => 'deviselabels'}, required: false, :input_html => {:maxlength => 15, :size => 40, class: 'lineitemdevise'} %> <%= f.input :email, :label_html => {:class => 'deviselabels'}, required: false, autofocus: false, placeholder: "Please use your work or university address", :input_html => {:maxlength => 55, :size => 40, class: 'lineitemdevise'} %> <%= f.input :password, :label_html => {:class => 'deviselabels'}, required: false, placeholder: "Minimum 8 characters", :input_html => {:maxlength => 15, :size => 40, class: 'lineitemdevise'} %> </div> <div class="form-actions"> <%= f.button :submit, "Join by email", :class => "dcpb" %> </div> <% end %> </div> </div>
I have another model called profile.rb.
profile belongs_to user
Problems:
- None of this works. When I click on each of the social media login links, the page just jumps to the sign up by email form.
The heroku logs error message says:
(facebook) Authentication failure! invalid_credentials: OAuth2::Error, : 2015-11-03T07:05:48.237549+00:00 app[web.1]: {"error":{"message":"Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request","type":"OAuthException","code":100,"fbtrace_id":"HD3mnzmSTEw"}}
- When I complete the sign up by email form with an email and password, the user name is recognised (in that the navbar says Hello , but when I go into the rails console, the user is not listed.
Also, when I click on the user name, I get an error which says that profile does not exist. The heroku logs say:
(Couldn't find Profile with 'id'=3)
- Is there another step required to make the social media registrations work to create a new user?
MY NEXT ATTEMPT:
I've changed all of the above and tried again, following the approach in the Railscasts videos.
I now use a user model and an authentications model.
In the user.rb, I have:
has_many :authentications, :dependent => :delete_all def apply_omniauth(omniauth) authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'], :token => auth['credentials']['token']) end
authentication.rb
belongs_to :user def self.from_omniauth(auth) where(auth.slice(:provider, :uid)).first_or_create do | user | authentication.provider = auth.provider authentication.uid = auth.uid authentication.user.first_name = auth.first_name authentication.user.last_name = auth.last_name authentication.user.image = auth.info.image end end
Authentications_controller:
class AuthenticationsController < ApplicationController before_action :set_authentication, only: [:destroy] def index @authentications = current_user.authentications if current_user end def create omniauth = request.env["omniauth.auth"] authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid']) if authentication sign_in_and_redirect_user(:user, authentication.user.profile) elsif current_user current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid']) redirect_to user.profile_url else user = User.new user.omniauth(omniauth) if user.save! sign_in_and_redirect_user(:user, user.profile) else session[:omniauth] = omniauth.except('extra') redirect_to new_user_registration_url end end end def destroy @authentication.destroy respond_to do |format| format.html { redirect_to authentications_url } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_authentication @authentication = current_user.authentications.find(params[:id]) end end
In the routes.rb, I have:
devise_for :users, :controllers => { :registrations => "users/registrations", } patch '/auth/:provider/callback' => 'authentications#create'
Omniauth.rb
require 'omniauth-facebook'require 'omniauth-google-oauth2'
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do provider :facebook, ENV['FACEBOOK_ID'], ENV['FACEBOOK_KEY'], :scope => 'public_profile', info_fields: 'id,first_name,last_name,link,email', :display => 'popup', :client_options => {:ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}}
Then when I try this, I get this error:
(facebook) Authentication failure! invalid_credentials: OAuth2::Error, : 2015-11-05T06:4839+00:00 app[web.1]: {"error":{"message":"Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request","type":"OAuthException","code":100,"fbtrace_id":"CrvXN22Z"}}
I find the next part of the error message odd because it refers to the callbacks controller which I no longer use (the whole thing is commented out and there is no route for it).
Authentication failure! invalid_credentials: OAuth2::Error, : 2015-11-05T08:24:16.010951+00:00 app[web.1]: Processing by Devise::OmniauthCallbacksController#failure as HTML 2015-11-05T08:24:16.012648+00:00 app[web.1]: Redirected to http://www.dder.com/users/sign_in
A FURTHER ATTEMPT
I have been trying to set up devise with omniauth for more than 1.5 years now. This is my latest attempt (following the Sitepoint tutorial at sitepoint.com/rails-authentication-oauth-2-0-omniauth). I've tried to use this tutorial before and not had any success, so I've made some tweaks to try and adapt it to some aspects of other tutorials on this topic.
I now have:
user.rb
has_many :authentications, :dependent => :delete_all def apply_omniauth(omniauth) authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'], :token => auth['credentials']['token']) end
authentication.rb
belongs_to :user def self.from_omniauth(auth) where(auth.slice(:provider, :uid)).first_or_create do | user | authentication.provider = auth.provider authentication.uid = auth.uid authentication.user.first_name = auth.first_name authentication.user.last_name = auth.last_name authentication.user.image = auth.info.image end end
authentications controller
class AuthenticationsController < Devise::OmniauthCallbacksController before_action :set_authentication, only: [:destroy] def index @authentications = current_user.authentications if current_user end def create omniauth = request.env["omniauth.auth"] authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid']) if authentication sign_in_and_redirect_user(:user, authentication.user.profile) elsif current_user current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid']) redirect_to user.profile_url else user = User.new user.omniauth(omniauth) if user.save! sign_in_and_redirect_user(:user, user.profile) else session[:omniauth] = omniauth.except('extra') redirect_to new_user_registration_url end end end def destroy @authentication.destroy respond_to do |format| format.html { redirect_to authentications_url } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_authentication @authentication = current_user.authentications.find(params[:id]) end end
registrations controller
class Users::RegistrationsController < Devise::RegistrationsController #before_filter :check_permissions , :only => [ :new, :create, :cancel ] #skip_before_filter :require_no_authentication # before_action :configure_permitted_parameters, if: :devise_controller? # Suggestion from Sitepoint tutorial - not currently implemented because not sure about the difference between this and set params. def check_permissions authorize! :create, resource end def index if params[:approved] == "false" @users = User.find_all_by_approved(false) else @users = User.all end end def create super session[:omniauth] = nil unless @user.new_record? end # THIS IS A SUGGESTION FROM SITEPOINT TUTORIAL # protected # def configure_permitted_parameters # devise_parameter_sanitizer.for(:sign_up) << [:first_name, :last_name] # end private def user_params params.require(:user).permit(:first_name, :last_name, :email, :password ) end def build_resource(*args) super if session[:omniauth] @user.apply_omniauth(session[:omniauth]) @user.valid? end end end
routes
devise_for :users, :controllers => { :registrations => "users/registrations", :omniauth_callbacks => "authentications" # :omniauth_callbacks => 'users/omniauth_callbacks', } get '/auth/:provider/callback' => 'authentications#create'
I can check these routes with:
rake routes | grep auth user_omniauth_authorize GET|POST /users/auth/:provider(.:format) authentications#passthru {:provider=>/facebook|linkedin|twitter|google_oauth2/} user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) authentications#:action GET /auth/:provider/callback(.:format) authentications#create
new registration partial in the view
<%- if devise_mapping.omniauthable? %> <div class="twitterauth"> <%= link_to "Join with Twitter", user_omniauth_authorize_path(:twitter) %> </div> <% end -%>
I'm really not sure where this path is coming from. Not sure why it's named as it is.
new session partial in the view
<%- if devise_mapping.omniauthable? %> <div class="twitterauth"> <%= link_to "Login with Twitter", user_omniauth_authorize_path(:twitter) %> </div> <% end -%>
Current error:
AbstractController::ActionNotFound at /users/auth/twitter/callback The action 'twitter' could not be found for AuthenticationsController
解决方案Devise comes with an out of the box solution for integration with omniuth. You can checkout these urls:1. https://www.digitalocean.com/community/tutorials/how-to-configure-devise-and-omniauth-for-your-rails-applicationThis one shows integration with DigitalOcean but can be extended to others.2. https://github.com/plataformatec/devise/wiki/OmniAuth%3A-OverviewThis one is from devise wiki
Hope it helps
这篇关于Rails,Devise& Omniauth - 设置问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!