0
votes

I am trying to set up a simple iOS/Rails application where I can create a user and subsequently authenticate them using BCrypt. I have tried to follow BCrypt's instructions but my authentication process is not working. Very new to rails so I'm sure I'm screwing up something simple!

To create a new user:

In users_controller.rb

# POST /users
# POST /users.json
def create
  @user = User.new(user_params)
  @user.password = user_params[:password]

 respond_to do |format|
  if @user.save
    format.html { redirect_to @user, notice: 'User was successfully created.' }
    format.json { render :show, status: :created, location: @user }
  else
    format.html { render :new }
    format.json { render json: @user.errors, status: :unprocessable_entity }
  end
 end
end

def user_params
    params.require(:user).permit(:username, :password)
end

In user.rb

def password
   @password ||= Password.new(password_hash)
end

def password=(new_password)
   @password = Password.create(new_password)
   self.password_hash = @password
end

On the server:

Started POST "/users.json" for 192.168.2.6 at 2014-08-21 19:32:05 -0500 Processing by UsersController#create as JSON Parameters: {"username"=>"testtest", "password"=>"[FILTERED]", "user"=>{"username"=>"testtest"}} (0.1ms) begin transaction User Exists (20.8ms) SELECT 1 AS one FROM "users" WHERE "users"."username" = 'testtest' LIMIT 1 Binary data inserted for string type on column password_hash SQL (0.8ms) INSERT INTO "users" ("created_at", "password_hash", "updated_at", "username") VALUES (?, ?, ?, ?) [["created_at", "2014-08-22 00:32:05.960378"], ["password_hash", "$2a$10$UzLdD7ytQXKRDU5MhAawJuFQ3R4oQlPyXh/V4GehNP692fsSpK6wK"], ["updated_at", "2014-08-22 00:32:05.960378"], ["username", "testtest"]] (1.3ms) commit transaction Rendered users/show.json.jbuilder (0.3ms) Completed 201 Created in 136ms (Views: 31.9ms | ActiveRecord: 23.5ms)

The authenticate a user:

In sessions_controller.rb

def create
    if @user = User.authenticate(params[:username], params[:password])
        session[:user_id] = @user.id
        render :show
    else
        flash.now[:alert] = "Invalid login/password combination"
        render :action => 'fail'
    end
end

In user.rb

def self.authenticate(username,password)
 @user = User.find_by_username(username)
 return @user.password == password
end

Server:

*Started POST "/session" for 192.168.2.6 at 2014-08-21 19:38:26 -0500 Processing by SessionsController#create as / Parameters: {"username"=>"testtest", "password"=>"[FILTERED]", "session"=>{"username"=>"testtest", "password"=>"[FILTERED]"}} User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."username" = 'testtest' LIMIT 1 Rendered sessions/fail.json.jbuilder (0.2ms) Completed 200 OK in 105ms (Views: 23.3ms | ActiveRecord: 0.2ms)*

Thanks much for any insight!

1

1 Answers

1
votes

Basically Bcrypt is used to encrypt password.

You can use this following method in user.rb model to encrypt the password and authenticate user.

before_save :encrypt_password
def self.authenticate(name, password)
  user = find_by_user_name(name)
  if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
    user
  else
    nil
  end
end

def encrypt_password
  if password.present?
    self.password_salt = BCrypt::Engine.generate_salt
    self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
  end
end