【问题标题】:Devise: Create User without Password then Require Password to Use Account?设计:创建没有密码的用户然后需要密码才能使用帐户?
【发布时间】:2011-07-11 17:53:06
【问题描述】:

我正在尝试使用 Devise 来布局 Rails 应用程序以进行身份​​验证。我想要一个初始登录页面,人们可以在其中输入电子邮件地址。我想在获得电子邮件地址后立即创建一个帐户,然后让用户稍后完成身份验证过程。是否有一些文档可以显示如何执行此操作?

谢谢!

【问题讨论】:

    标签: ruby-on-rails-3 authentication devise


    【解决方案1】:

    我最终通过使用“devise_invitable”gem 解决了这个问题。为了使这项工作正常进行,我必须扩展的唯一一件事是确保用户不需要经过身份验证即可发送邀请。覆盖邀请控制器,它工作得很好:

    class InvitationsController < Devise::InvitationsController
      include Devise::Controllers::InternalHelpers
    
      skip_filter :authenticate_inviter!
      skip_filter :authenticate!
    
      def current_inviter
        @current_inviter ||= User.new(params[:user])
      end
    end
    

    【讨论】:

      【解决方案2】:

      我不确定是否有很好的文档说明如何执行此操作,但这并不难。只是不需要在您的登录页面或该页面上登录表单的帖子上进行身份验证。在登录表单中收集电子邮件地址。向用户发送邮件到他们登录时使用的地址。在电子邮件中,包含“忘记密码”链接(重命名为“单击此处登录”......或其他)以强制用户登录并选择密码。这对你有用吗,还是我错过了什么?

      【讨论】:

      • 是的,这基本上就是我想要做的。我会尝试看看它是如何工作的。
      • 祝你好运 - 我已经实现了类似的东西,它工作正常 - 在这里睡觉,但会在早上回来查看并尝试回答任何问题,如果没有其他人接听它们
      【解决方案3】:

      我意识到这已经晚了,但这可能对其他人有所帮助。我和你有类似的要求。基本上,我想让用户输入电子邮件地址,并将用户作为访客保留。将用户提升为“普通”用户后,我将重新启用密码身份验证。首先,我基于devise-gullible gem 创建了一个守望者策略。我对authenticate方法做了修改:

      class Guest < Authenticatable
        def authenticate!
          resource = mapping.to.find_for_database_authentication(authentication_hash)
          if resource
            if resource.respond_to?(:guest?) and resource.guest?
              success!(resource)
            else
              fail(:regular_user)
            end
          else
            fail(:invalid)
          end
        end
      end
      

      我在我的用户模型中定义了一个访客用户,如下所示:

      def guest?
          self.roles.length == 0
      end
      

      我正在使用带有设计和 HABTM 的 CanCan 来处理角色。目前,我有一个“普通”用户和一个“管理员”用户。如果用户尚未分配角色,则该用户是访客。

      然后,您需要覆盖设计注册控制器:

      class Users::RegistrationsController < Devise::RegistrationsController
        prepend_before_filter :allow_params_authentication!, :only => :create
      
        def create
          resource = warden.authenticate(:guest,
                                         { scope: resource_name,
                                           recall: "#{controller_path}#new" })
          if resource
            set_flash_message(:notice, :signed_in) if is_navigational_format?
            sign_in(resource_name, resource)
            respond_with resource, :location => after_sign_in_path_for(resource)
          elsif warden.winning_strategy.message == :regular_user
            set_flash_message :notice, :regular_user if is_navigational_format?
            redirect_to new_session_path(resource_name)
          else
            super
          end
        end
      end
      

      请注意,这个想法是我们尝试仅对运行访客策略的用户进行身份验证。如果他已经注册为访客,只需正常登录即可。如果访客策略因为他已注册而失败,但现在是普通用户,则重定向到正常登录页面。

      现在可以保留我可能希望从客人那里收集的一些有限信息,而不要求他必须进行完整的注册。我使用普通的用户模型:

      class User < ActiveRecord::Base
        devise :database_authenticatable, :registerable, :confirmable,
          :recoverable, :rememberable, :trackable, :omniauthable,
          :token_authenticatable
      
        # Setup accessible (or protected) attributes for your model
        attr_accessible :email, :password, :password_confirmation, :remember_me
      
        has_and_belongs_to_many :roles
      
        def self.new_with_session(params, session)
          super.tap do |user|
            if user.password.blank?
              user.password = Devise.friendly_token[0,31]
              # Also, we don't need to do email confirmation in this case.
              # The user will have the guest role, and we'll do a confirmation
              # when we promote him to a 'regular' user.
              user.skip_confirmation!
            end
          end
        end
      
        def has_role?(role)
          !!self.roles.find_by_name(role.to_s.camelize)
        end
      end
      

      请注意,我在build_with_session 中自动生成密码。您可以在您选择的时候发送一个身份验证令牌,然后要求用户在那个时候设置一个新密码。然后,您还需要更改他的角色,以便他成为普通用户(或做任何您想要说明他不再是客人的事情)。

      这是我在首页上显示的部分内容:

      <%= simple_form_for(resource,
                          as: resource_name,
                          url: user_registration_path,
                          defaults: { required: false },
                          html: { class: 'well' },
                          wrapper: :bootstrap,
                          validate: true) do |f| %>
        <%= f.error_notification %>
        <fieldset>
          <legend>New here? Let's get started!</legend>
          <%= f.input :email, placeholder: 'user@example.com', validate: { uniqueness: false } %>
          <%= f.button :submit, "Get my quote!", class: 'btn-primary' %>
        </fieldset>
      <% end %>
      

      因此,此表单既可用作访客注册表单,也可用作登录表单。到目前为止,我真正关心的唯一想法是注册控制器正在处理身份验证,但我没有看到解决此问题的直接方法。

      我在我的本地 lib 目录中实施了这个策略。请务必正确设置加载路径,并将require 'devise_guest' 添加到config/initializers/devise.rb

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-15
        • 1970-01-01
        • 2015-07-23
        • 2017-04-12
        相关资源
        最近更新 更多