22

Làm cách nào tôi có thể ghi đè current_user của tạo đá quý. Thực ra tôi cần thêm dịch vụ web cho ứng dụng dành cho thiết bị di động.Nơi để ghi đè phương pháp trình trợ giúp hiện tại của người tạo ra đá quý

Hiện tại, nhà phát triển đang quản lý phiên và 'current_user' cho ứng dụng web.

Ứng dụng dành cho thiết bị di động sẽ gửi user_id tới máy chủ. Tôi cần ghi đè người dùng hiện tại như thế này

def current_user 
    if params[:user_id].blank? 
    current_user 
    else 
    User.find(params[:user_id]) 
    end 
end 

Tôi có cần phải sửa đổi đá quý như một plugin? hoặc cái gì khác?
Vui lòng giải thích chi tiết như tôi mới trong đường ray.

Trân trọng!

+2

yikes ... vậy, bạn đang nói khi một đại lý di động gửi lên user_id bạn sẽ chỉ tin tưởng nó? –

+0

cũng có một số khóa bí mật xác thực –

+0

Devise sẽ xử lý token_authenticatable đó - chỉ cần vượt qua authentication_token, không cần user_id. –

Trả lời

46

Theo module Devise::Controllers::Helpers, current_user (cùng với tất cả những người giúp đỡ devise khác) sẽ được thêm vào ApplicationController, có nghĩa là bạn có thể ghi đè lên nó theo cách này:

# in application_controller.rb 
alias_method :devise_current_user, :current_user 
def current_user 
    if params[:user_id].blank? 
    devise_current_user 
    else 
    User.find(params[:user_id]) 
    end 
end 
+8

Lỗi trên hàng "alias_method": undefined_method 'current_user' cho lớp ApplicationController (NameError), khi khởi động môi trường của tôi. Nếu tôi nhận xét nó ra, khởi động, và bỏ ghi chú, nó hoạt động tốt. Có một sửa chữa? – Frexuz

+5

Frexuz, hãy thử thay thế alias_method bằng một cái gì đó như: def devise_current_user {@devise_current_user || = warden.authenticate (: scope =>: user)} –

+0

có an toàn không? Tôi nhận được lỗi nil trong các điểm kỳ lạ trong bộ điều khiển sau khi xác thực trên MRI. –

5

Các câu trả lời khác cho thấy răng cưa phương pháp thực sự không phải là giải pháp tốt nhất. bình luận Doug tiếng Anh là giải pháp tốt nhất:

# In ApplicationHelper 
def devise_current_user 
    @devise_current_user ||= warden.authenticate(:scope => :user) 
end 

Dưới đây là lý do:

Giả sử bạn đang kể ApplicationHelper của bạn trong điều khiển của bạn. Nếu bạn cần một phương thức trong ApplicationHelper của bạn dựa trên devise_current_user, được cung cấp giải pháp bí danh bên trong controller, bạn sẽ không gặp may.

Nhưng với định nghĩa phương thức rõ ràng ở trên, bạn có thể di chuyển định nghĩa đến trình trợ giúp và gọi nó từ các phương pháp khác và bạn vẫn có thể đưa nó vào bộ điều khiển. Điều này rất hữu ích, ví dụ, khi bạn đang phát triển một giải pháp mạo danh người dùng và bạn cần hiển thị hai người dùng khác nhau trong chế độ xem, một cho người quản trị thực (devise_current_user) và người kia, người dùng bị mạo danh (current_user) .

+2

Thực ra bạn đúng. Xin lưu ý rằng những điều sau đây nên được bao gồm trong 'ApplicationController': 'include ApplicationHelper'. Nếu không, 'devise_current_user' sẽ không được biết. –

0

Giả sử chúng ta có thể tin tưởng dữ liệu phiên của chúng tôi (mà dựa vào việc bạn đưa vào sử dụng trong đó mà không được phép thích hợp hay không), điều này có thể làm việc như một quan tâm:

module Concerns 
    module ControllerWithImpersonation 
    extend ActiveSupport::Concern 

    included do 
     helper_method :devise_current_user 
    end 

    def current_user 
     if session[:impersonated_user_id].blank? 
     devise_current_user 
     else 
     User.find(session[:impersonated_user_id]) 
     end 
    end 

    def devise_current_user 
     @devise_current_user ||= warden.authenticate(:scope => :user) 
    end 

    end 
end 

Tôi đang sử dụng điều này trong một dự án cho bây giờ.

Một câu hỏi nhỏ (trong câu trả lời, xin lỗi) ... tôi có nên biết bất kỳ thay đổi nào trong Devise hoặc Warden làm cho số devise_current_user ở trên đã lỗi thời không?

0

Limbo-Peng của câu trả lời là rất tốt, nhưng có thể được cải thiện một chút để đảm bảo chỉ quản trị viên có thể làm điều này:

Bạn sẽ cũng cần phải xác định một phương pháp is_admin? hoặc is_admin thuộc tính trên lớp người dùng.

Bạn cũng có thể muốn sử dụng một khóa khác với user_id, vì vậy nó sẽ không bao giờ xung đột với các thông số thông thường của bạn.

# to impersonate another user, e.g. for customer support 
# only admins can do this.. 
# 
alias_method :devise_current_user, :current_user 
def current_user 
    if ! params[:user_id].blank? \ 
    && devise_current_user && devise_current_user.is_admin? 
    User.find(params[:user_id]) 
    else 
    devise_current_user 
    end 
end 
Các vấn đề liên quan