Hi!
I have just added login feature to my rails application (followed the
instruction from (Agile Web D. with Rails) but now I am getting
strange errors (looks to me like some kind of routing problem) under the
passenger/apache.
The error is:
500 Internal Server Error
The server encountered an internal error or misconfiguration and was
unable to complete your request.
From the log:
e[4;36;1mSQL (0.3ms)e[0m e[0;1mSET SQL_AUTO_IS_NULL=0e[0m
Processing Controller#index (for 192.168.1.101 at 2010-04-26
18:56:24) [GET]
e[4;35;1mUser Columns (1.7ms)e[0m e[0mSHOW FIELDS FROM users
e[0m
e[4;36;1mUser Load (0.7ms)e[0m e[0;1mSELECT * FROM users
WHERE
(users
.id
IS NULL) LIMIT 1e[0m
Redirected to https://**/login/login_page
Filter chain halted as [:authorize] rendered_or_redirected.
Completed in 31ms (DB: 3) | 302 Found [https://******/]
Does anybody has any suggestion what I could do?
class LoginController < ApplicationController
def add_user
@user = User.new(params[:user])
if request.post? and @user.save
flash.now[:notice] = “User #{@user.name} created”
@user = User.new
end
end
def login_page
session[:user_id] = nil
if request.post?
user = User.authenticate(params[:name], params[:password])
if user
session[:user_id] = user.id
session[:user_name] = user.name
uri = session[:original_uri]
session[:original_uri] = nil
redirect_to(uri || { :action => “index” })
else
flash[:notice] = “Invalid user/password combination”
end
end
end
def logout
session[:user_id] = nil
flash[:notice] = “Logged out”
redirect_to(:action => “login_page”)
end
def index
end
def delete_user
if request.post?
user = User.find(params[:id])
if User.count == 1
flash[:notice] = “You can’t remove last remaining user!”
else
user.destroy
end
end
redirect_to(:action => :list_users)
end
def list_users
@all_users = User.find(:all)
end
end
class ApplicationController < ActionController::Base
before_filter :authorize, :except => :login_page
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection
for details
def create_default_variables(ctrl_name)
session[:ctrl_name] = ctrl_name
end
Scrub sensitive parameters from your log
filter_parameter_logging :password
private
def authorize
unless User.find_by_id(session[:user_id])
session[:original_uri] = request.request_uri
flash[:notice] = “Please log in”
redirect_to(:controller => “login”, :action => “login_page”)
end
end
end
require ‘digest/sha1’
class User < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
attr_accessor :password_confirmation
validates_confirmation_of :password
def validate
errors.add_to_base(“Missing password”) if hashed_password.blank?
end
def self.authenticate(name, password)
user = self.find_by_name(name)
if user
expected_password = encrypted_password(password, user.salt)
if user.hashed_password != expected_password
user = nil
end
end
user
end
‘password’ is a virtual attribute
def password
@password
end
def password=(pwd)
@password = pwd
create_new_salt
self.hashed_password = User.encrypted_password(self.password,
self.salt)
end
def after_destroy
if User.count.zero?
raise “Can’t delete last user”
end
end
private
def self.encrypted_password(password, salt)
string_to_hash = password + “wibble” + salt # ‘wibble’ makes it
harder to guess
Digest::SHA1.hexdigest(string_to_hash)
end
def create_new_salt
self.salt = self.object_id.to_s + rand.to_s
end
end
login_page.html.erb
Name: <%= text_field_tag :name, params[:name] %>
Password: <%= password_field_tag :password, params[:password] %>
<%= submit_tag "Login" %>
<% end %>ActionController::Routing::Routes.draw do |map|
map.resources :controller1
map.resources :controller2
…
map.root :controller => “controller1”
map.connect ‘:controller/:action/:id’
map.connect ‘:controller/:action/:id.:format’
end