2013-02-27 3 views
2

사용자가 로그인하기 전에 게시물을 만들 수있는 컨트롤러 PostsController가 있습니다.하지만 저장하려면 Omniauth를 사용하여 로그인해야합니다. 가 PostsController에서before_filter 다른 컨트롤러의 메서드 사용

, 내가 가진 :

class PostsController < ApplicationController 
    before_filter :authenticate_user_by_service, :only => :create 
    def create 
    ... 
    end 

private 
    def authenticate_user_by_service 
    redirect_to user_omniauth_authorize_path(:facebook) 
    end 

을 지금, 나는 ServicesController

라고 페이스 북에서 콜백을 처리 할 수있는 또 다른 컨트롤러가
class ServicesController < ApplicationController 
    def create 
    auth = request.env["omniauth.auth"] 
    ... authentication logic here ... 
    sign_in(:user, service.user) 
    end 
    method_alias: :facebook, :create 

일반적으로, 인증, 로그인 한 후에 I 리디렉션 대상 : back.

그러나 여기서 services#create은 before_filter로 사용됩니다. 이 경우 내 게시물 # 만들기로 되돌리려면 어떻게해야합니까?

업데이트 : 필터 체인을 말하는이 경고를 가지고 바로 내가 당신 잘못이 접근하고 다른 방법

Started POST "/posts" for 127.0.0.1 at 2013-02-26 23:47:41 -0500 
Processing by PostsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"H0as8=", "post"=>{"post"=>"bla bla"}, "commit"=>"Create Post"} 
Redirected to http://localhost:3000/users/auth/facebook 
Filter chain halted as :authenticate_user_by_service rendered or redirected 

답변

1

를 참조 순간에 중단됩니다. 로그인을 처리하고 누군가가 같은 단계로 로그인했는지 확인합니다.

예를 들어, 모든 가입/로그인/로그 아웃 로직을 처리하는 sessions_controller 사용을 고려 :

class SessionsController < ApplicationController 
    def new # this will be /login 
    session[:return_to] = params[:returnto] unless params[:returnto].nil? 
    redirect_to "/auth/facebook" 
    end 

    def create # this will be the callback after the user is authenticated 
    auth_token = request.env["omniauth.auth"]["credentials"]["token"] 
    # you'll need to write this based on your app's requirement. 
    # Find a user or create one if he doesn't exist yet. 
    user = User.find_or_create_authenticated_user(auth_token) 

    if user.present? 
     session[:user_id] = user.id # this stores the current user's id in your session and lets Rails remember him for you. 
     redirect_to return_or(products_url) # see below for the usage of return_or 
     return 
    end 

    redirect_to root_url, alert: 'User not found or invalid' 
    end 

    def destroy # /logout 
    session[:user_id] = nil 
    redirect_to root_url 
    end 
end 


#routes.rb 
match '/logout' => 'sessions#destroy', :as => :logout 
match '/login' => 'sessions#new', :as => :login 
match '/auth/facebook/callback' => 'sessions#create' 

를 그런 다음에 ApplicationController 당신은 헬퍼 방법 중 몇 가지 설정 :

class ApplicationController < ActionController::Base 

    protected 
    # Use this in your views and controllers to get 
    # a handle of the user that is currently logged in. 
    # it will return nil if there is no user logged in. 
    def current_user 
    @current_user ||= User.find(session[:user_id]) if session[:user_id] 
    end 
    helper_method :current_user 

    # Use this to check wether a user is logged in. 
    # returns true if there is a user, false otherwise. 
    def logged_in? 
    !current_user.nil? 
    end 
    helper_method :logged_in? 

    # Block access to controllers or actions based on 
    # wether there's a user or not. 
    def require_login 
    unless logged_in? 
     # if we need the user to log in, we send him on his way 
     # but send him back to the current page afterwards. 
     session[:return_to] = request.fullpath 
     redirect_to root_url(subdomain: false), :alert => "Please login" 
    end 
    end 

    # When a user is not logged in, but you send him to log in, 
    # you can force him to return to the url he was in or if nothing 
    # was set go to a standard path. 
    # See this being set up in SessionsController#new and in require_login and then 
    # being used in SessionsController#create 
    def return_or(path) 
    session.delete(:return_to) || path 
    end 
    helper_method :return_or 
end 

을 이 도우미 메서드는 모두 ApplicationController에서 상속되므로 모든 컨트롤러에서 사용할 수 있습니다. 그런 다음 PostsController에 가서 로그인하지 않은 사용자를 보내고 로그인 한 후 PostsController로 돌아가도록 할 수 있습니다.

인증 후 게시물 저장 요구 사항을 해결하려면 다음과 같이하십시오. 게시물을 작성하여 저장하고 사용자가 인증 된 후에 공개로 만 업데이트하거나 게시물의 내용을 세션을 만들고 사용자가 인증 된 후에 복원하십시오.

class PostsController < ApplicationController 
    def new 
    @post = Post.new(session[:post_params] || {}) 
    end 

    def create 
    if logged_in? 
     @post = Post.create(params[:post]) 
     # ... etc 
    else 
     session[:post_params] = params[:post] 
     session[:return_to] = new_post_path 
    end 
    end 
end 

이는 다소 취약한 접근 방법입니다. 차라리 실제로는 Post을 만들고 아직 공개하지 않았다고 표시하고 해당 게시물의 id 만 세션에 저장하는 것이 좋습니다. 인증 후에는 post_id를 찾고, 오브젝트를 다시 작성하고, 상태를 public으로 설정하고이를 current_user와 연관시킬 수 있습니다.

+0

매우 자세한 답변을 제공해 주셔서 감사합니다. 사용자가 로그인하지 않으면 Posts # create에서 어떤 일이 일어나는지 친절하게 설명 할 수 있습니까? 이 메소드 내에서 require_login을 호출해야합니까? – AdamNYC