0

I am trying to work through the rails tutorial, and ran into a problem. In the process of debugging it I ran into this strange behavior, which I think is related to my problem.

>rails console
DL is deprecated, please use Fiddle
Loading development environment (Rails 3.2.16)
irb(main):001:0> app.cookies['foo'] = 'bar'
=> "bar"
irb(main):002:0> app.cookies['remember_token'] = 'foobar'
=> "foobar"
irb(main):003:0> app.cookies['foo']
=> "bar"
irb(main):004:0> app.cookies['remember_token']
=> "foobar"
irb(main):005:0> app.put app.root_url
  User Load (1.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" IS NULL LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" IS NULL LIMIT 1
=> 200
irb(main):006:0> app.cookies['foo']
=> "bar"
irb(main):007:0> app.cookies['remember_token']
=> ""

Notice how cookies['foo'] remains set to 'bar' after a put, but cookies['remember_token'] gets set to ""

Can anyone explain what might be going on here? I do have a column "remember_token" in the model, but I don't see how that should come into play.

Here is the model:

class User < ActiveRecord::Base
  attr_accessible :email, :name, :password, :password_confirmation
  has_secure_password
  validates :name, presence: true, 
                   length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true,
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  validates :password, presence: true,
                       length: { minimum: 6 }
  validates :password_confirmation, presence: true                     
  before_save { email.downcase! }
  before_save :create_remember_token


    private

    def create_remember_token
      puts "in create remember_token"  #added for debug
      self.remember_token = SecureRandom.urlsafe_base64
      puts remember_token   #added for debug
    end

end

and here is the database :

ActiveRecord::Schema.define(:version => 20140111165943) do

  create_table "users", :force => true do |t|
    t.string   "name"
    t.string   "email"
    t.datetime "created_at",      :null => false
    t.datetime "updated_at",      :null => false
    t.string   "password_digest"
    t.string   "remember_token"
  end

  add_index "users", ["email"], :name => "index_users_on_email", :unique => true
  add_index "users", ["remember_token"], :name => "index_users_on_remember_token"

end

My original question was related to test failures , and can be found here

Update: Found source of this strange behavior

As I began to get together the code to show the full controller (as requested in the comment), it became clear that this was going to be the source of my problem.

class ApplicationController < ActionController::Base
  protect_from_forgery
  include SessionsHelper

  # Force signout to prevent CSRF attacks
  def handle_unverified_request
    sign_out
    super
  end


end

and here is the sign_out method (in my sessions_helper)

def sign_out
    puts "in sign out"
    cookies.delete :remember_token
    self.current_user = nil
  end

I added a puts in the sign_out method and saw that it was called as soon as a did a put (but not a get). Now I have to back to the tutorial and see what I must have done wrong.

Community
  • 1
  • 1
nPn
  • 16,254
  • 9
  • 35
  • 58
  • 1
    Please show full controller including sign in method – Billy Chan Jan 19 '14 at 07:45
  • @BillyChan thanks, that request was all I needed to figure it out. First thing I did was to open up the ApplicationController and found the above code (updated in my question) – nPn Jan 19 '14 at 14:03
  • 1
    nPn, nice you figured it out by yourself! Controller is the only possible place to make such changes. – Billy Chan Jan 19 '14 at 14:29

1 Answers1

0

The issue here was a result of having protect_from_forgery on and a sign_out method in handle_unverified_request. See the update at the end of the question for the details

nPn
  • 16,254
  • 9
  • 35
  • 58