Tôi nhận ra điều này là muộn, nhưng điều này có thể hữu ích cho người khác. Tôi đã có một yêu cầu tương tự như bạn. Về cơ bản, tôi muốn người dùng nhập địa chỉ email và tiếp tục sử dụng với tư cách khách. Khi người dùng được thăng cấp thành người dùng 'thông thường', tôi bật lại xác thực mật khẩu. Đầu tiên, tôi tạo ra một chiến lược bảo vệ dựa trên đá quý devise-gullible. Tôi đã thực hiện một thay đổi phương pháp 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
tôi xác định một người dùng khách trong mô hình của tôi sử dụng như sau:
def guest?
self.roles.length == 0
end
Tôi đang sử dụng Cancan với devise và một HABTM để xử lý các vai trò. Hiện tại, tôi có người dùng 'thông thường' và người dùng 'quản trị'. Người dùng là khách nếu anh ấy chưa có vai trò được chỉ định nào.
Sau đó, bạn cần phải ghi đè bộ điều khiển đăng ký devise:
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
Lưu ý rằng ý tưởng là chúng tôi cố gắng để xác thực người dùng chạy các chiến lược của khách mà thôi. Nếu anh ta đã đăng ký với tư cách khách, chỉ cần đăng nhập anh ấy bình thường. Nếu chiến lược khách thất bại vì anh ta đã được đăng ký nhưng hiện là người dùng thông thường, hãy chuyển hướng đến trang đăng nhập thông thường.
Bây giờ, có thể tồn tại một số thông tin giới hạn mà tôi có thể muốn thu thập từ khách và không yêu cầu anh ta phải đăng ký đầy đủ. Tôi sử dụng kiểu người dùng bình thường:
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
Lưu ý rằng tôi tự động tạo mật khẩu trong build_with_session
. Bạn có thể gửi mã thông báo xác thực tại thời điểm bạn chọn và sau đó yêu cầu người dùng đặt mật khẩu mới tại thời điểm đó. Bạn cũng sẽ muốn sau đó thay đổi vai trò của mình để trở thành người dùng thông thường (hoặc làm bất cứ điều gì bạn muốn lưu ý anh ấy không còn là khách).
Dưới đây là một phần của tôi xuất hiện trên trang đầu:
<%= 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: '[email protected]', validate: { uniqueness: false } %>
<%= f.button :submit, "Get my quote!", class: 'btn-primary' %>
</fieldset>
<% end %>
Vì vậy, hình thức này có chức năng như cả một đăng ký khách và mẫu đăng nhập.Chỉ nghĩ rằng tôi không thực sự quan tâm cho đến nay là bộ điều khiển đăng ký đang xử lý một xác thực, nhưng tôi đã không nhìn thấy một cách ngay lập tức xung quanh này.
Tôi đã triển khai chiến lược này trong thư mục lib cục bộ của mình. Đảm bảo đặt đường dẫn tải của bạn một cách thích hợp và thêm require 'devise_guest'
vào config/initializers/devise.rb
.
Yup, đó là cơ bản những gì tôi đang cố gắng làm. Tôi sẽ thử nghiệm để xem cách hoạt động của nó. – spinlock
chúc may mắn - Tôi đã thực hiện một cái gì đó như thế này và nó hoạt động tốt - giờ đi ngủ ở đây nhưng sẽ kiểm tra lại vào buổi sáng và cố gắng trả lời bất kỳ truy vấn nếu không ai khác chọn chúng – chrispanda