2013-04-11 34 views
15

Ở đây tôi đang sử dụng Devise Gem để xác thực. Nếu ai đó muốn mở trang mà không cần đăng nhập thì nó sẽ chuyển hướng đến trang sign_in và sau khi đăng nhập lại trang mà người dùng cố gắng mở. Tôi sử dụng liên kết Redirect loop with Devise after_sign_in_path_for cho sự cố của mình nhưng nó không hoạt động đối với tôi.Phát sinh chuyển hướng trở lại vị trí ban đầu sau khi đăng nhập hoặc đăng ký?

def after_sign_in_path_for(resource) 
    params[:next] || super 
end 

Nó không chuyển hướng tôi về trang mà tôi muốn mở. Ví dụ: : Nếu tôi muốn mở "127.0.0.1:3000/post/2/edit", nó không thể quay lại trang này sau khi đã đăng nhập.

Trả lời

33

Tài nguyên tốt nhất để tìm kiếm là repo/wiki/chính thức/vấn đề, và sau đó SO. Câu trả lời bạn tìm thấy đã lỗi thời.

Dưới đây là câu trả lời: https://github.com/plataformatec/devise/wiki/How-To:-Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up,-update

Chỉ cần thêm những điều sau đây trong ApplicationController

after_filter :store_location 

def store_location 
    # store last url as long as it isn't a /users path 
    session[:previous_url] = request.fullpath unless request.fullpath =~ /\/users/ 
end 

def after_sign_in_path_for(resource) 
    session[:previous_url] || root_path 
end 
+1

Cảm ơn @Billy trả lời của bạn .. trong khi sử dụng mã này, nó luôn luôn chuyển hướng tôi đến root_path (home page) và không có trong trang cụ thể mà tôi mở trước khi đăng nhập – Rajeev

+0

@rubydev, làm bạn sử dụng Firefox và addon để vô hiệu hóa liên kết giới thiệu? Cũng sử dụng công cụ gỡ lỗi, nói thêm '<% = debug session =>' trong template, hoặc rails console để kiểm tra những gì đã xảy ra. –

+4

Cảm ơn @Billy, công việc của nó bây giờ, Chỉ có một thay đổi ở đây là tôi thay đổi after_filter thành before_filter – Rajeev

0

tôi có nghi ngờ giống nhau và tìm thấy này, hãy thử nó quá

def after_sign_in_path_for(resource_or_scope) 
    session.fetch 'user_return_to', admin_root_path 
end 
17

Bạn don' t cần tất cả các mã này. Devise (là phiên bản mới nhất) đã lưu vị trí cho bạn.

Chỉ cần sử dụng này:

def after_sign_in_path_for(resource) 
    request.env['omniauth.origin'] || stored_location_for(resource) || root_url 
end 

này sẽ chuyển hướng người dùng đến omniauth.source mới nhất, hoặc stored_location và là trường hợp cuối cùng, url gốc.

Tôi nghĩ mình đã được yêu cầu tạo phương thức đó, nhưng Devise đã làm điều đó.

Nguồn: https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in

2

Tính đến Devise 4, nó làm việc liên tục cho tôi:

lập mưu tự động chuyển hướng về đăng nhập và đăng ký miễn là bạn lưu trữ vị trí của trang hiện tại sử dụng đưa ra của store_location_for(resource). Để thực hiện việc này, hãy chỉnh sửa ApplicationController của bạn trong app/controllers/application_controller.rb. Địa chỉ:

# saves the location before loading each page so we can return to the 
# right page. If we're on a devise page, we don't want to store that as the 
# place to return to (for example, we don't want to return to the sign in page 
# after signing in), which is what the :unless prevents 
before_filter :store_current_location, :unless => :devise_controller? 

private 
    # override the devise helper to store the current location so we can 
    # redirect to it after loggin in or out. This override makes signing in 
    # and signing up work automatically. 
    def store_current_location 
    store_location_for(:user, request.url) 
    end 

Thêm dòng sau vào ApplicationController để làm đăng xuất chuyển hướng:

private 
    # override the devise method for where to go after signing out because theirs 
    # always goes to the root path. Because devise uses a session variable and 
    # the session is destroyed on log out, we need to use request.referrer 
    # root_path is there as a backup 
    def after_sign_out_path_for(resource) 
    request.referrer || root_path 
    end 
3

Như đã chỉ ra trong các tài liệu chính thức, simpler solution sẽ chỉ đơn giản là thêm video này vào application_controller.rb của bạn :

class ApplicationController < ActionController::Base 


private 

# If your model is called User 
def after_sign_in_path_for(resource) 
    session["user_return_to"] || root_path 
end 

Lưu ý quan trọng (I cũng bị bỏ qua) là để làm việc này bạn sẽ cần phải gọi phương thức authenticate_user!, có sẵn theo mặc định trong Devise, trong bộ điều khiển của bạn là before_action:.Điều này sẽ gọi store_location_for có sẵn out of the box in Devise và phần còn lại được xử lý bằng mã ở trên trong application_controller.rb, do đó loại bỏ sự cần thiết phải viết lại mã để lưu url yêu cầu.

+1

Giải pháp này hoạt động cho dù với 'remote: true' cũng như không có, trong khi giải pháp @Billy Chan chỉ hoạt động mà không có. – Vadim

0

Một số giải pháp khác ở đây có thể không hoạt động nếu biểu mẫu đăng nhập của bạn có trang riêng, thay vì, ví dụ: biểu mẫu đăng nhập trong tiêu đề của mỗi trang. Sau khi đăng nhập, người dùng cần quay lại hai trang, không chỉ một trang.

Devise có cách làm đẹp trên Redirecting back to the current page after sign in, sign out, update, từ đó mã bên dưới xuất hiện.

Lưu trữ URL gốc trong phiên là tùy chọn tốt nhất. Ngoài việc giải quyết vấn đề trên quay trở lại hai trang, "Nhiều trình duyệt không gửi tiêu đề [request.referer]. Do đó, cách trình duyệt chéo duy nhất mạnh mẽ để triển khai chức năng này là sử dụng phiên".

Khi lưu trữ URL trong phiên, điều quan trọng là không lưu trữ URL cho bất kỳ yêu cầu POST, PUT hoặc DELETE nào cũng như bất kỳ yêu cầu XHR nào, tức là không có gì mà người dùng thực sự không thể được chuyển hướng.

Lưu ý rằng sau khi đăng xuất, phiên của người dùng sẽ bị hủy, vì vậy URL đã lưu sẽ biến mất. Trong trường hợp này, người dùng có thể được gửi trở lại request.referer. Điều này có vẻ chấp nhận được vì hầu hết các trang web đều có liên kết đăng xuất trên mỗi trang, vì vậy việc quay lại liên kết giới thiệu sẽ thực sự hoạt động.

class ApplicationController < ActionController::Base 
    before_action :store_user_location!, if: :storable_location? 
    before_action :authenticate_user! 

    private 
    def storable_location? 
     request.get? && is_navigational_format? && !devise_controller? && !request.xhr? 
    end 

    def store_user_location! 
     store_location_for(:user, request.fullpath) 
    end 

    def after_sign_in_path_for(resource_or_scope) 
    stored_location_for(resource_or_scope) || super 
    end 

    def after_sign_out_path_for(resource_or_scope) 
    request.referrer || super 
    end 
end 
Các vấn đề liên quan