How to make authentication for a Rail API application
When finishing the project for my phase 3 at Flatiron School, I found myself interested in the authentication part the most. By using Bcrypt gem, we can make authentication for our single page application built in Javascript. I created a Github repo of a Rails API with a basic HTML page for the frontend part and an MVC for just 1 table “user”. The repo is attached at the end of this blog, you can use it to code along.
Our page right now will look like below.
We will together to make authentication for our page. If someone signs up or logs in with correct information, they can see the secret message.
For now, my database just has one table named “users” with attributes “name”, “age”, “email” without any data. If you run “rails server” inside of directory “blog-auth-app/backend”, you will able to access this URL http://localhost:3000/users
with no user yet.
So for the authentication, we will use Bcrypt gem. So go to the Gemfile and uncomment this line:
gem 'bcrypt', '~> 3.1.7'
Then bundle install. For Bcrypt gem working, you need to have attribute password_digest
for your table “users”. We will save the password hashes in a password_digest
column in the database instead of the password itself.
So run in your terminal:
rails g migration AddPasswordToUsers password_digest
Then run “rails db:migrate” again. So now our schema will look like this:
In your user model, you also need “has_secure_password
" method. It will add 2 fields in our model: password
and password_confirmation
.
In “main.js” file, it was already created a method createUser
. But it lacks attribute password
and password_confirmation
You will need to add 2 below lines to that method.
The res_status
variable above is the response that is passed down from our create action in the user controller. Our create method looks like below. If the user is created successfully, it will respond to an object with status and user information. That object is passed down to res_status
variable above.
Then if the new user cannot save, that means it doesn’t pass our validations or some other reasons. In Rails, we have the way to capture all the errors by running this:
user.errors.full_message
You can see above, it will respond to an object with errors
as the key and passed it to our js file. Then now res_status.errors
will be an array of all errors, we can print it out for users to see. Right now, I already put the validations that require the presence of age and email. If I leave that two boxes empty string and click submit, it will notify the errors like this.
Interesting, right? Now we know the way we can capture the errors on the backend and make them appear on the frontend part. Feel free to add more validations for users.
For the login part, the function in main.js
file is almost the same (you can uncomment the code below create part), except the URL. You’ll need to add a new route for your routes.rb
file. You can name whatever you want for URL link, just make it the same in routes.rb
file and main.js
file.
post '/authUser', to: "users#auth"
When someone posts information (POST REQUEST) to this URL http://localhost:3000/users
, it will execute the auth
action in users controller. That’s why we need to create the auth
action.
Our auth
action in users controller looks the same as create
action above but it adds the authenticate
method to check user password. We can use authenticate
the method thanks to Bcrypt gem
. If it is true, we will pass the object {status: 200, user: user} to our frontend. Otherwise, it renders the object that contained the keymessage
: "Wrong email or password".
Finally, this is the secret message that will appear when you sign up or log in successfully.
Github repo. Feel free to clone and code along with this blog.
Happy Coding!