Sinatra Project: User Authentication

In reviewing my project, I realized I had forgotten to do a crucial step in my program — authenticating my users. What exactly is user authentication and why is it so important?

User authentication essentially verifies a user, or proves the identity of a user, when they are logged into any application. Their identity is verified, or authenticated page to page while they are logged on so they do not have access to another user’s information, and vice versa. So if a person logs into their Instagram account, they can only see their profile, post to their profile, edit/delete something on their profile...you get the idea.

My sinatra app is an online grocery store that allows a user to place an online order. So in regards to my app, I will be working with a user’s username and password. I first validated a User’s username in my User Model and installed the ‘bycrypt’ gem which allows access to a method called “has_secure_password”. This allows our application to be protected against hacking attempts and helps us authenticate our user.

   has_secure_password
validates :username, presence: true
validates :username, uniqueness: true
has_many :ordersend

Moving on to the User Controller, I had to modify my post ‘/users/login’ route to allow a conditional that will assign the session to the user’s user_id, and redirect that user to their homepage. If the credentials are not recognized, I want my program to show an error (for this I used the flash gem) and redirect them to the login page again:

@user = User.find_by(username: params[:username])if @user && @user.authenticate(params[:password])
session[:user_id] = @user.id
redirect "/users/#{@user.id}"
else
flash[:error] = "No account associated with those credentials please try again."
redirect '/users/login'
end
end

As stated before, the bcrypt gem gives us access to methods that secure passwords and authenticate, as seen above in the line of code “@user.authenticate(params[:password])”. There are other gems you could utilize, but I prefer bcrypt.

Great — my program now secures a user’s password and authenticates a user when they log in. However, my program still allows any user to access ALL of the orders placed, from all different user’s. This also means a user can edit/delete an order that wasn’t made by them. Let’s fix that!

In my Orders Controller I coded my logic as follows:

#=>update
get '/orders/:id/edit' do
@order = Order.find(params[:id])
if current_user == @order.user
erb :'/orders/edit'
else
redirect '/users/welcome'
end
end
#=>delete
delete '/orders/:id' do
@order = Order.find(params[:id])
if current_user == @order.user
@order.destroy
redirect '/orders'
else
redirect '/orders/welcome'
end
end

Now, a user can only see the orders created on their account, edit those orders, and delete those orders. That user does not have access to any other user’s account information. Bingo, our program is secure!

Software Engineering graduate with a penchant for matcha lattes and baked goods. Most of my content will consist of RoR, JS, HTML/CSS, and React.