ruby-on-rails – Rails 4 – 设计Omniauth并允许单个用户通过多种社交媒体策略进行身份验证

ruby-on-rails – Rails 4 – 设计Omniauth并允许单个用户通过多种社交媒体策略进行身份验证,第1张

概述我正在尝试用Rails 4创建一个应用程序. 我一直在尝试(3年)弄清楚如何使Devise和Omniauth工作,以便用户可以在他们的用户配置文件中添加多个社交媒体帐户. 我已经阅读了所有的设计和omniauth文档.我可以使用这些文档获得的最佳效果是添加1个单独的社交媒体帐户.那不是我想要的. 我试过这个网站点教程 sitepoint.com/rails-authentication-oauth 我正在尝试用Rails 4创建一个应用程序.

我一直在尝试(3年)弄清楚如何使Devise和Omniauth工作,以便用户可以在他们的用户配置文件中添加多个社交媒体帐户.

我已经阅读了所有的设计和omniauth文档.我可以使用这些文档获得的最佳效果是添加1个单独的社交媒体帐户.那不是我想要的.

我试过这个网站点教程
sitepoint.com/rails-authentication-oauth-2-0-omniauth

我试过这个willschenck教程
http://willschenk.com/setting-up-devise-with-twitter-and-facebook-and-other-omniauth-schemes-without-email-addresses/

我试过这个jorge.caballeromurillo教程:http://jorge.caballeromurillo.com/multiple-omniauth-providers-for-same-user-on-ruby-on-rails/

我也尝试过这个源代码的教程:http://sourcey.com/rails-4-omniauth-using-devise-with-twitter-facebook-and-linkedin/

在试图找到这个问题的帮助时,我已经在SO上承诺了数以千计的积分 – 但还没有想出来.在过去的3年里,我去过我所在地区的每一次铁路聚会,并且在代理商上试图找到帮助时浪费了$$$.自最近一次令人沮丧的尝试准备再给它一次以来,已经过去了足够的时间.请帮忙.

这是我到目前为止所拥有的:

User.rb

devise :database_authenticatable,:registerable,:recoverable,:rememberable,:trackable,:confirmable,:lockable,# :zxcvbnable,:omniauthable,:omniauth_provIDers => [:facebook,:linkedin,:twitter,:Google_oauth2 ]has_many :IDentitIEs,dependent: :destroydef self.find_for_oauth(auth,signed_in_resource = nil)    # Get the IDentity and user if they exist    IDentity = IDentity.find_for_oauth(auth)    # If a signed_in_resource is provIDed it always overrIDes the existing user    # to prevent the IDentity being locked with accIDentally created accounts.    # Note that this may leave zombIE accounts (with no associated IDentity) which    # can be cleaned up at a later date.    user = signed_in_resource ? signed_in_resource : IDentity.user    # p '11111'    # Create the user if needed    if user.nil?      # p 22222      # Get the existing user by email if the provIDer gives us a verifIEd email.      # If no verifIEd email was provIDed we assign a temporary email and ask the      # user to verify it on the next step via UsersController.finish_signup      email_is_verifIEd = auth.info.email && (auth.info.verifIEd || auth.info.verifIEd_email)      email = auth.info.email if email_is_verifIEd # take out this if stmt for chin yi's solution      user = User.where(:email => email).first if email      # Create the user if it's a new registration      if user.nil?        # p 33333        user = User.new(          # at least one problem with this is that each provIDer uses different terms to desribe first name/last name/email. See notes on linkedin above          first_name: auth.info.first_name,last_name: auth.info.last_name,email: email ? email : "#{TEMP_EMAIL_PREFIX}-#{auth.uID}-#{auth.provIDer}.com",#username: auth.info.nickname || auth.uID,password: Devise.frIEndly_token[0,20])# fallback for name fIElds - add nickname to user table        # deBUGger        # if email_is_verifIEd           user.skip_confirmation!        # end        # user.skip_confirmation!         user.save!      end    end    # Associate the IDentity with the user if needed    if IDentity.user != user      IDentity.user = user      IDentity.save!    end    user  end  def email_verifIEd?    self.email && TEMP_EMAIL_REGEX !~ self.email  end

IDentity.rb

belongs_to :user  valIDates_presence_of :uID,:provIDer  valIDates_uniqueness_of :uID,:scope => :provIDerdef self.find_for_oauth(auth)    find_or_create_by(uID: auth.uID,provIDer: auth.provIDer)  end

用户控制器:

class UsersController < ApplicationControllerbefore_action :set_user,only: [ :show,:edit,:update,:finish_signup,:destroy]  def index    # if params[:approved] == "false"    #   @users = User.find_all_by_approved(false)    # else      @users = User.all      authorize @users      # end  end  # GET /users/:ID.:format  def show    # authorize! :read,@user  end  # GET /users/:ID/edit  def edit    # authorize! :update,@user    authorize @user  end  # PATCH/PUT /users/:ID.:format  def update    # authorize! :update,@user    respond_to do |format|      authorize @user      if @user.update(user_params)        sign_in(@user == current_user ? @user : current_user,:bypass => true)        # I'm trying to get the user matched to an organisation after the email address (in finish sign up) updates the user model.        UserOrganisationMapperService.call(@user)        format.HTML { redirect_to @user }#,notice: 'Your profile was successfully updated.' }        format.Json { head :no_content }      else        format.HTML { render action: 'edit' }        format.Json { render Json: @user.errors,status: :unprocessable_entity }      end    end  end  # GET/PATCH /users/:ID/finish_signup  def finish_signup    # authorize! :update,@user    if request.patch? && params[:user] #&& params[:user][:email]      if @user.update(user_params)        @user.skip_reconfirmation!        # @user.confirm!        sign_in(@user,:bypass => true)        redirect_to root_path#,notice: 'Your profile was successfully updated.'        # redirect_to [@user,@user.profile || @user.build_profile]        # sign_in_and_redirect(@user,:bypass => true)      else        @show_errors = true      end    end  end  # DELETE /users/:ID.:format  def destroy    # authorize! :delete,@user    @user.destroy    authorize @user    respond_to do |format|      format.HTML { redirect_to root_url }      format.Json { head :no_content }    end  end  private    def set_user      @user = User.find(params[:ID])      authorize @user    end    def user_params      # params.require(:user).permit(policy(@user).permitted_attributes)      accessible = [ :first_name,:last_name,:email,:avatar,{role_IDs: []} ] # extend with your own params      accessible << [ :password,:password_confirmation ] unless params[:user][:password].blank?      # accessible << [:approved] if user.admin      params.require(:user).permit(accessible)    endend

身份控制器

class IDentitIEsController < ApplicationController  before_action :set_IDentity,only: [:show,:destroy]  before_action :authenticate_user!  # GET /IDentitIEs  # GET /IDentitIEs.Json  def index    @IDentitIEs = IDentity.all  end  # GET /IDentitIEs/1  # GET /IDentitIEs/1.Json  def show  end  # GET /IDentitIEs/new  def new    @IDentity = IDentity.new  end  # GET /IDentitIEs/1/edit  def edit  end  # POST /IDentitIEs  # POST /IDentitIEs.Jsondef create    @IDentity = IDentity.new(IDentity_params)    respond_to do |format|      if @IDentity.save        format.HTML { redirect_to @IDentity,notice: 'IDentity was successfully created.' }        format.Json { render :show,status: :created,location: @IDentity }      else        format.HTML { render :new }        format.Json { render Json: @IDentity.errors,status: :unprocessable_entity }      end    end  end  # PATCH/PUT /IDentitIEs/1  # PATCH/PUT /IDentitIEs/1.Json

创造我也尝试过的替代方案

def create  auth = request.env['omniauth.auth']  # Find an IDentity here  @IDentity = IDentity.find_with_omniauth(auth)  if @IDentity.nil?    # If no IDentity was found,create a brand new one here    @IDentity = IDentity.create_with_omniauth(auth)  end  if signed_in?    if @IDentity.user == current_user      # User is signed in so they are trying to link an IDentity with their      # account. But we found the IDentity and the user associated with it       # is the current user. So the IDentity is already associated with       # this user. So let's display an error message.      redirect_to root_url,notice: "Already linked that account!"    else      # The IDentity is not associated with the current_user so lets       # associate the IDentity      @IDentity.user = current_user      @IDentity.save      redirect_to root_url,notice: "Successfully linked that account!"    end  else    if @IDentity.user.present?      # The IDentity we found had a user associated with it so let's       # just log them in here      self.current_user = @IDentity.user      redirect_to root_url,notice: "Signed in!"    else      # No user associated with the IDentity so we need to create a new one      redirect_to new_registration_path,notice: "Please finish registering"    end  endenddef update    respond_to do |format|      if @IDentity.update(IDentity_params)        format.HTML { redirect_to @IDentity,notice: 'IDentity was successfully updated.' }        format.Json { render :show,status: :ok,location: @IDentity }      else        format.HTML { render :edit }        format.Json { render Json: @IDentity.errors,status: :unprocessable_entity }      end    end  end  # DELETE /IDentitIEs/1  # DELETE /IDentitIEs/1.Json  def destroy    @IDentity.destroy    respond_to do |format|      format.HTML { redirect_to IDentitIEs_url,notice: 'IDentity was successfully destroyed.' }      format.Json { head :no_content }    end  end  private    # Use callbacks to share common setup or constraints between actions.    def set_IDentity      @IDentity = IDentity.find(params[:ID])    end    # Never trust parameters from the scary internet,only allow the white List through.    def IDentity_params      params[:IDentity]    endend

注册控制器

class Users::RegistrationsController < Devise::RegistrationsController  before_action :configure_permitted_parameters,if: :devise_controller?  def create    super do |resource|      UserOrganisationMapperService.call(resource)    end  end  protected  def configure_permitted_parameters    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email,:password,:first_name,:last_name) }  end  privateend

omn​​iauth回调控制器

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController  #sourcey tutorial ------------------  def self.provIDes_callback_for(provIDer)    class_eval %Q{      def #{provIDer}        @user = User.find_for_oauth(env["omniauth.auth"],current_user)         if @user.persisted?          sign_in_and_redirect @user,event: :authentication        else          session["devise.#{provIDer}_data"] = env["omniauth.auth"]          redirect_to new_user_registration_url        end      end    }  end  [:twitter,:facebook,:Google_oauth2].each do |provIDer|    provIDes_callback_for provIDer  endend

用户/完成注册视图

<div >   <div >    <div >     <h1 >Complete your registration</h1>        <%= form_for(current_user,:as => 'user',:url => finish_signup_path(current_user),:HTML => { role: 'form'}) do |f| %>        <% if @show_errors && current_user.errors.any? %>          <div ID="error_explanation">          <% current_user.errors.full_messages.each do |msg| %>            <%= msg %><br>          <% end %>          </div>        <% end %>    <div >      <!--  f.label :false  -->      <div >        <% if current_user.first_name.blank? %>              <%= f.text_fIEld :first_name,:value => '',class: 'form-control input-lg',placeholder: 'First name' %>            <p >Hi there,what is your first name?.</p>        <% end %>        <% if current_user.last_name.blank? %>              <%= f.text_fIEld :last_name,placeholder: 'Last name (surname)' %>            <p >Add your last name</p>        <% end %>            <% if !current_user.email_verifIEd? %>           <%= f.text_fIEld :email,placeholder: 'Example: [email protected] -- use your primary work or university address' %>           <p >Please confirm your email address. No spam.</p>        <% end %>         </div>    </div>    <div >      <%= f.submit 'Continue',:class => 'btn btn-primary' %>    </div>    <% end %>    </div>  </div></div>

用户/身份验证视图

<div >   <div >        <div >            <div  >                <table >                    <tr>                      <td><i ></i></td>                         <td>                        <% if @user.IDentitIEs.map(&:provIDer).include?('facebook') %>                            <span </span>                        <% else %>                              <%= link_to icon('Connect Facebook',ID: 'facebookauth'),user_omniauth_authorize_path(:facebook) %>                        <% end %>                         </td>                    </tr>                    <tr>                      <td><i ></i></td>                       <td>                        <% if @user.IDentitIEs.map(&:provIDer).include?('Googleauth') %>                            <span </span>                        <% else %>                              <%= link_to icon('Connect Google',ID: 'Googleauth'),user_omniauth_authorize_path(:Google_oauth2) %>                        <% end %>                         </td>                    </tr>                    <tr>                      <td><i ></i></td>                         <td>                        <% if @user.IDentitIEs.map(&:provIDer).include?('linkedin') %>                            <span </span>                        <% else %>                              <%= link_to icon('Connect linkedin',ID: 'linkedinauth'),user_omniauth_authorize_path(:linkedin) %>                        <% end %>                      </td>                    </tr>                    <tr>                      <td><i ></i></td>                          <td>                        <% if @user.IDentitIEs.map(&:provIDer).include?('twitter') %>å                           <span </span>                        <% else %>                              <%= link_to icon('Connect Twitter',ID: 'twitterauth'),user_omniauth_authorize_path(:twitter) %>                        <% end %>                      </td>                    </tr>                    <tr>                      <td>Password</td>                       <td>                        <% if @user.encrypted_password.present? %>                            <span </span>                        <% else %>                               <%= form_for(current_user,:HTML => { role: 'form'}) do |f| %>                                <% if @show_errors && current_user.errors.any? %>                                    <div ID="error_explanation">                                        <% current_user.errors.full_messages.each do |msg| %>                                            <%= msg %><br>                                        <% end %>                                    </div>                                <div >                                    <div >                                          <%= f.input :password,hint: ("#{@minimum_password_length} characters minimum" if @valIDatable),:input_HTML => { class: 'estimate-password'} %>                                    </div>                                </div>                                  <% end %>                            <div >                                <%= f.submit 'Continue',:class => 'btn btn-primary' %>                            </div>                        <% end %>                      </td>                    </tr>                </table>            </div>          </div>   </div></div>

路线

devise_for :users,#class_name: 'FormUser',:controllers => {                :registrations => "users/registrations",# :omniauth_callbacks => "users/authentications"                :omniauth_callbacks => 'users/omniauth_callbacks'           }  # PER SOURCEY TUTORIAL ----------  match '/users/:ID/finish_signup' => 'users#finish_signup',via: [:get,:patch],:as => :finish_signup

这些都不起作用.我不知道如何插入它.我不确定我是否应该在控制器允许的参数中包含存储在我的身份表中的属性?

属性是:

t.integer  "user_ID"    t.string   "provIDer"    t.string   "accesstoken"    t.string   "refreshtoken"    t.string   "uID"    t.string   "name"    t.string   "email"    t.string   "nickname"    t.string   "image"    t.string   "phone"    t.string   "urls"

我有这个工作,所以用户只能使用一种方法进行身份验证.我不知道如何让这个工作.我已经尝试了所有可以找到的资源来解决这个问题,但我陷入困境.

我将这一切都与每个社交插件和电子邮件一起使用,但我没有的是能够向现有用户添加身份(在当前会话中),以便下次登录时他们可以使用任何可接受的身份.

有人可以帮忙吗?

解决方法 由于无法查看所有代码,我只创建了一个与多个提供程序一起运行的shell应用程序.我只是按照你在 sourcey提到的教程中的步骤进行 *** 作.这是我 repo的链接.

您应该能够克隆它并通过在devise.rb初始化程序中从facebook,twitter和linkedin输入应用程序的密钥和秘密令牌来运行它.要使其在本地工作,您需要确保twitter上的回调网址设置为http://127.0.0.1:3000/.

如果您想让用户选择添加他们自己的omniauth帐户(身份),而不是通过应用程序授权自动完成,您只需为用户输入一个表单输入数字uID并在控制器中创建自己的身份或者这样的后端:

new_IDentity = IDentity.newnew_IDentity.user_ID = "current user's ID"new_IDentity.provIDer = "facebook"new_IDentity.uID = "0123456789"new_IDentity.save!

用户必须从站点获取他们的数字uID并自己输入.

总结

以上是内存溢出为你收集整理的ruby-on-rails – Rails 4 – 设计Omniauth并允许单个用户通过多种社交媒体策略进行身份验证全部内容,希望文章能够帮你解决ruby-on-rails – Rails 4 – 设计Omniauth并允许单个用户通过多种社交媒体策略进行身份验证所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1277117.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存