简体   繁体   中英

Rails Auth, Remember me

I'm trying to add remember me functionality to my login form by following Ryan Bates's tutorial . However when I try to access my pages I get this error:

Couldn't find User with auth_token =

I think the problem is coming from my application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery
  helper_method  :current_user

  private

  def current_user
    @current_user ||= User.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
  end
end

Here's the code from my user.rb

class User < ActiveRecord::Base
  attr_accessible :username, :email, :password, :password_confirmation
  has_secure_password   

  validates_presence_of :username
  validates_uniqueness_of :username
  validates_presence_of :email
  validates_uniqueness_of :email
  validates_confirmation_of :password
  validates_presence_of :password, :on => :create

  before_create { generate_token(:auth_token) }

  def send_password_reset
    generate_token(:password_reset_token)
    self.password_reset_sent_at = Time.zone.now
    save!
    UserMailer.password_reset(self).deliver
  end

  def generate_token(column)
    begin
      self[column] = SecureRandom.urlsafe_base64
    end while User.exists?(column => self[column])
  end
end

Here's my user_controller.rb

class UsersController < ApplicationController
  def new
    @user = User.new
   end

  def show
    @user = User.find(params[:id])
  end

  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to @user, :notice => "Signed up!"
    else
     render "new"
    end
  end
end

And finally here is my sessions_controller

class SessionsController < ApplicationController
  def new
  end

  def create
    user = User.find_by_username(params[:username])
    if user && user.authenticate(params[:password])
      if params[:remember_me]
        cookies.permanent[:auth_token] = user.auth_token
      else
        cookies[:auth_token] = user.auth_token
      end
      redirect_to root_url, :notice => "Logged in!"
    else
      flash.now.alert = "Invalid email or password"
      render "new"
    end
  end

  def destroy
    cookies.delete(:auth_token)
    redirect_to root_url, :notice => "Logged out!"
  end
end

The only thing I changed was finding the user by username instead of email but I can't see why that would break it. Anyone got any ideas?

Edit

My database is populated by the following migrations

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :username
      t.string :email
      t.string :password_digest

      t.timestamps
    end
  end
end

class AddAuthTokenToUsers < ActiveRecord::Migration
  def change
    add_column :users, :auth_token, :string
  end
end

class AddPasswordResetToUsers < ActiveRecord::Migration
  def change
    add_column :users, :password_reset_token, :string
    add_column :users, :password_reset_sent_at, :datetime
  end
end
end

Here is the error according to the terminal window:

ActionView::Template::Error (Couldn't find User with auth_token = ):
    1: <h1>Home</h1>
    2: 
    3: <div id="user_nav">
    4:   <% if current_user %>
    5:     Logged in as <%= current_user.email %>
    6:     <%= link_to "Log out", logout_path %>
    7:   <% else %>
  app/controllers/application_controller.rb:8:in `current_user'
  app/views/pages/home.html.erb:4:in `_app_views_pages_home_html_erb___725535246_2189699680'

Edit 2

Here is the code for the home.html.erb file

<h1>Home</h1>

<div id="user_nav">
  <% if current_user %>
    Logged in as <%= current_user.email %>
    <%= link_to "Log out", logout_path %>
  <% else %>
    <%= link_to "Sign up", signup_path %> or 
    <%= link_to "Log in", login_path %>
  <% end %>
</div>

This may not be -the- answer, but have you tried something like:

<h1>Home</h1>

<div id="user_nav">
  <% if !current_user.auth_token.nil? %>
    Logged in as <%= current_user.email %>
    <%= link_to "Log out", logout_path %>
  <% else %>
    <%= link_to "Sign up", signup_path %> or 
    <%= link_to "Log in", login_path %>
  <% end %>
</div>

I suspect that, for some reason, auth_token is null for current_user. You can also try modifying the logic to something like:

<div id="user_nav">
    cu nil?:<%=current_user.nil?%>
    cu.at.nil?:<%=current_user.auth_token.nil? if !current_user.?nil%>
    <%= link_to "Log out", logout_path %>
    <%= link_to "Sign up", signup_path %> or 
    <%= link_to "Log in", login_path %>
</div>

... while you are debugging this issue. At least that should get you a little more information and a page that loads while you dig further.

I had the same issue. The problem was only occurring for users that I had in my database before I added the auth_token field to the user database table. The App Couldn't find User with auth_token as the older users didn't have one created for them when they signed up as this functionality was not implemented then.

To overcome this I simply deleted the older users from my database & signed them up again.

However users where no longer being logged in automatically. To over come this I changed this line:

session[:user_id] = @user.id

to

cookies[:auth_token] = @user.auth_token

As I was now using a cookie rather than a session to sign users in.

I was having this same issue and after reading all of these posts and the ideas at RailsCasts I tried updating the application controller to check if the auth_token being returned from the cookie actually contained something and it started working.

def current_user
    @current_user ||= User.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token] && cookies[:auth_token].length > 0
end

I'm not sure if cookies[:auth_token] was returning nil and the conditional wasn't catching it or if cookies[:auth_token] was actually returning an empty string and the User.find_by_auth_token didn't like it, even though it worked in the the console.

Not sure if this is the right way to go or not but thought I would throw it out there.

Thanks Patrick

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM