0

Your help is hugely appreciated and valued. Thank you in advance if you take some of your time to read this issue and eventually respond.

I'm working with a standard authentication system storing a user_id and remember_token in cookies. When filling-in a login form, a new token gets generated for this user, and stored in cookies as such:

# Remembers a user in a persistent session.
  def remember(user)
    user.remember      # Generates a remember token + digest and saves the digest on the user side
    cookies.signed.permanent[:user_id] = user.id
    cookies.permanent[:remember_token] = user.remember_token
  end

I noticed the issue when after submitting the form with correct login information, the user always got redirected immediately back to the login page.

This is because the user_id and remember_token were nil when reaching the action following sessions#create. They also did not appear in the console of the browser (tried on Safari and Chrome with identical results). I thought the cookies were lost during the redirect.

But playing further, I included attempts to write cookies directly on a regular 'get' action, before any redirect:

class SessionsController < ApplicationController

  def new
    cookies[:hello] = {value: 'store_me_please', expires: 10.years.from_now}
    cookies.permanent[:a_true_cookie] = true
    cookies.permanent.signed[:remember_me] = 123
    session[:hello] = 'store_me_in_session_please'

    if logged_in?
      redirect_to user_path(current_user)
    else
      render layout: "unauthenticated"
    end
  end
end

And noticed that the cookie store in the browser would remain invariably empty while accessing the action. Nothing would get written.

I thought it could be caused by a csrf protection problem as rails can clear the session if it fails to authenticate its token. So I commented out "protect_from_forgery" in the application_controller, but saw no change.

The secret_key_base seems to be in place in the new credentials.yml file; although it's the first Rails 5.2 App for which I deal with such issues, so I could be missing something in the configuration.

I also added the following configuration line to application.rb, which then triggers a "ActionController::InvalidAuthenticityToken" exception on submitting the form, despite the "#protect_from_forgery with: :exception" line being commented out.

config.session_store :cookie_store

It seems to me that the cookies are never sent out by the Rails App to the browser. What could cause this behavior?

Charles
  • 1
  • 2
  • Check the response header of your request whether it is sending set_cookie or not. It should send set_cookie in every request until and unless you skip it manually. – Vishal Mar 02 '20 at 11:11
  • Thanks for looking into it! From what I see in the browser, no "set_cookie" header is passed back by Rails. I'm proceeding to looking into why this would not be the case, but I'd gladly take your idea on it if you have one! – Charles Mar 02 '20 at 12:44
  • By adding manually the set-cookie header, I see that it seems filtered out by the browser: " response.set_header('Set-Cookie', ':hellohere=yeshello') " Does not appear in the headers received by the browser; but: " response.set_header('X-Set-Cookie', ':hellohere=yeshello') " Does appear in the list. Could that indicate something with security options? – Charles Mar 02 '20 at 12:58
  • In the meantime, while printing the headers of the response directly on the server, I notice that my manual addition of both X-Set-Cookie and Set-Cookie get added to the headers by the server, but not for other cookies I would set normally. – Charles Mar 02 '20 at 13:07
  • If you want to set custom cookie in your response header you can use this `session[:session_id] = SecureRandom.base64(8)` while `request.session_options[:skip] = true` this code will skip cookies to send in response header . check in your project , did you use this code anywhere in the application. – Vishal Mar 02 '20 at 13:30
  • Because its default behaviour to send cookies in every response header. It won't work unless you skip it manually. – Vishal Mar 02 '20 at 13:30
  • Thanks a lot for your help. Unfortunately could not find a way to return to normal cookie behavior, so I monkey patched it. :) – Charles Mar 02 '20 at 18:42

1 Answers1

0

I could not find any clean way around this issue, or find the exact cause. My intuition goes toward the following possible causes (only for documentation purpose, in case someone hits the same issue): - Cookie signature problem caused by a corrupted secret_key_base - CSRF/CORS issue also caused by a corrupted secret_key_base or interference with authenticity token, causing rails to dismiss the cookies before sending the response. - Some config setting not set properly preventing a normal execution.

I spent 3 full time days trying to diagnose what was causing this and still was unlucky. The only solution I could come up with was to transfer all the files of this non-functional App, to a copy of a functional one, with a practically identical config. The process took an hour and solved the issue -but alas did not give the cause.

Charles
  • 1
  • 2