No release in over 3 years
Low commit activity in last 3 years
cookieless_sessions implements a fallback mechanism for keeping Session-IDs (via GET-Parameter) on clients that doesn't support or allow cookies.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
 Dependencies

Development

~> 1.5
~> 2.2
~> 2.4
~> 0.9
<= 5.1.0, >= 4.0.0
~> 10.0
>= 3.6.1, ~> 3.6
~> 1.3

Runtime

 Project Readme

CookielessSessions

Gem Version Build Status Code Climate Dependency Status

CookielessSessions implements a fallback mechanism for keeping Session-IDs (via GET-Parameter) on clients that doesn't support or allow cookies.

By default, the server sends a Set-Cookie header to the client. If the client supports and allows cookies, it will send back this Cookie header back in the next request. If not, then there won't be a Cookie header in the next requests from the client to the server and the server will initiate a new session for the client, in every request. In this case, sessions won't work.

This is what this gem was built for. There is only one other way to transfer a Session-ID between server and client: via GET-Paramters (and of course POST-Parameters).

Implementation

There isn't any magic in this gem. This gem consists of one module which implements a concern for controllers. The important method in this module is default_url_options and it only adds the session_key with the session_id to the options hash.

Rails uses the result of default_url_options method for Path / URL generation. Because of that, the session_key and session_id will be added to every Paths and URL generated in (cookieless_session enabled) controllers.

Requirements

An application based on Rails 4.x or 5.x configured with a session storage that supports the cookie_only: false option (e.g. redis-session-store).

Installation

Add this line to your application's Gemfile:

gem 'cookieless_sessions'

And then execute:

$ bundle

Or install it yourself as:

$ gem install cookieless_sessions

Usage

First, you need a cookie storage which supports the cookie_only option and turn it off. Rails built in session storages (cookie_store and active_record_store) doesn't support this option. That's why you need another cookie_storage. For example: this gem uses redis_session_store from the redis-session-store gem and a Redis database for its tests.

Include the module into the controller where you want to enable sessions via GET parameter:

    class YourController < ApplicationController
        include CookielessSessions::EnabledController

        # ...
    end

If you want to enable sessions via GET parameter for the whole application, include the module into your ApplicationController:

    class ApplicationController < ActionController::Base
        include CookielessSessions::EnabledController

        # ...
    end

If you want to disable sessions via GET parameter for a certain controller, you can do this by excepting the sessions_key from the default_url_options:

    class OtherController < ApplicationController
        def default_url_options
            super.except(session_key)
        end
    end

Hint

If you want to overwrite default_url_options in one of your controllers that use cookieless_sessions and you want to keep that functionality, you should use super.dup and work on a copy:

    class AnotherController < ApplicationController
        def default_url_options
            options ||= super.dup || {}
            options[:foo] = :bar
            return options
        end
    end

Security

There is one security impact: If you copy & paste a URL with your Sessions-ID to a friend and he has cookies disabled (this won't be happen if he has cookies enabled), he will get your session (e.g. he will be logged in with your account, depends on the application).

Two countermeasure could be to bind sessions to the client's IP-Address and add a session lifetime. For both you can use the frikandel gem. This should make it harder to steal and fix sessions.

Test

To run the test suite with different rails version by selecting the corresponding gemfile. You can use this one liners:

$ export BUNDLE_GEMFILE=Gemfile.rails-4.0.x && bundle update && bundle exec rake spec
$ export BUNDLE_GEMFILE=Gemfile.rails-4.1.x && bundle update && bundle exec rake spec
$ export BUNDLE_GEMFILE=Gemfile.rails-4.2.x && bundle update && bundle exec rake spec
$ export BUNDLE_GEMFILE=Gemfile.rails-5.0.x && bundle update && bundle exec rake spec
$ export BUNDLE_GEMFILE=Gemfile.rails-5.1.x && bundle update && bundle exec rake spec
$ export BUNDLE_GEMFILE=Gemfile.rails-5.2.x && bundle update && bundle exec rake spec

Changes

  • v1.2.0 -- added support for rails-5.1
  • v1.1.0 -- added support for rails-5.0; remove support for rails-3.2
  • v1.0.1 -- added Rails32DestroyableSessionPatch: sets SID in options on destroy
  • v1.0.0 -- first release with complete README; no code changes
  • v0.0.2 -- improved and more flexible version with tests
  • v0.0.1 -- initial and work-in-progress version without any tests

Contributing

  1. Fork it ( https://github.com/taktsoft/cookieless_sessions/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request