Rails 3 disabling session cookies

前端 未结 10 1887
梦如初夏
梦如初夏 2020-11-30 00:06

I have RESTful API written on RoR 3. I have to make my application not to send \"Set-Cookie header\" (clients are authorizing using auth_token parameter).

I have tri

相关标签:
10条回答
  • 2020-11-30 00:42

    As is mentioned in a comment on John's answer, clearing the session will not prevent the session cookie from being sent. If you wish to totally remove the cookie from being sent, you have to use Rack middleware.

    class CookieFilter
      def initialize(app)
        @app = app
      end
    
      def call(env)
        status, headers, body = @app.call(env)
    
        # use only one of the next two lines
    
        # this will remove ALL cookies from the response
        headers.delete 'Set-Cookie'
        # this will remove just your session cookie
        Rack::Utils.delete_cookie_header!(headers, '_app-name_session')
    
        [status, headers, body]
      end
    end
    

    Use it by creating an initializer with the following body:

    Rails.application.config.middleware.insert_before ::ActionDispatch::Cookies, ::CookieFilter
    

    To prevent the cookie filter to end up in application stack traces, which can be utterly confusing at times, you may want to silence it in the backtrace (Assuming you put it in lib/cookie_filter.rb):

    Rails.backtrace_cleaner.add_silencer { |line| line.start_with? "lib/cookie_filter.rb" }
    
    0 讨论(0)
  • 2020-11-30 00:43

    I'm not sure when they added it to Devise, but there appears to be a configuration that will let you disable the sending of the session cookie when using a auth_token:

    # By default Devise will store the user in session. You can skip storage for
    # :http_auth and :token_auth by adding those symbols to the array below.
    # Notice that if you are skipping storage for all authentication paths, you
    # may want to disable generating routes to Devise's sessions controller by
    # passing :skip => :sessions to `devise_for` in your config/routes.rb
    config.skip_session_storage = [:http_auth, :token_auth]
    

    It does work well. The only issue I had was that I still needed to be able to make an initial request to my token_controller in order to generate/retrieve the token. I.e. POST /api/v1/tokens.json, which unfortunately would cause a session cookie to be returned for that request.

    So I ended up implementing the CookieFilter intializer that Ryan Ahearn wrote above anyway.

    Also, since my app has both a web front-end as well as a JSON api, I only wanted to filter the cookies for the JSON api. So I modified the CookieFilter class to first check the requests belonged to the api:

    if env['PATH_INFO'].match(/^\/api/)
      Rack::Utils.delete_cookie_header!(headers, '_myapp_session')
    end
    

    Not sure if there's a better way of doing that...

    0 讨论(0)
  • 2020-11-30 00:46

    Another solution: In the controller you want to avoid cookies, add this:

    after_filter :skip_set_cookies_header
    
    def skip_set_cookies_header
      request.session_options = {}
    end
    

    If you have a set of api controllers, set this in an api_controller class and let your other controllers inherit the api_controller.

    This skips setting Set-Cookie header since the session opts is empty.

    0 讨论(0)
  • 2020-11-30 00:48

    The default CookieSessionStore doesn't send a "Set-Cookie" header unless something is added to the session. Is something in your stack writing to the session? (it's probably Devise)

    session :off has been deprecated:

    def session(*args)
      ActiveSupport::Deprecation.warn(
        "Disabling sessions for a single controller has been deprecated. " +
        "Sessions are now lazy loaded. So if you don't access them, " +
        "consider them off. You can still modify the session cookie " +
        "options with request.session_options.", caller)
    end
    

    If something in your stack is setting session info, you can clear it using session.clear like so:

    after_filter :clear_session
    
    def clear_session
      session.clear
    end
    

    Which will prevent the Set-Cookie header from being sent

    0 讨论(0)
提交回复
热议问题