Welcome to the first lesson of our course, "Securing and Testing Your Ruby on Rails App." Today, we'll be focusing on user authentication, ensuring user passwords are stored securely using Bcrypt and managing authentication with JWT (JSON Web Tokens).
Authentication is a cornerstone of application security, protecting user data, and controlling access to specific parts of your app. Bcrypt is a proven library for securely hashing and storing passwords, making it computationally difficult for attackers to crack them. JWTs enable secure transmission of information as a JSON object, facilitating robust authentication management. By the end of this lesson, you'll be equipped to integrate JWT-based authentication in your Ruby on Rails app.
Let's dive right in!
First, we need to create a User model to store user information, including their securely hashed passwords. This model will encapsulate user-related data and behaviors.
Run the following Rails generator command to create the User model with username and password_digest fields:
Explanation:
- The
rails generate model User username:string password_digest:stringcommand creates a newUsermodel withusernameandpassword_digestattributes. - The
rails db:migratecommand applies the migration, creating theuserstable in the database with the specified attributes.
With the User model in place, we'll add password hashing functionality using the has_secure_password method provided by Rails.
Open the user.rb model file (app/models/user.rb) and add the following:
Explanation:
class User < ApplicationRecord: Defines theUsermodel, inheriting fromApplicationRecord.has_secure_password: Uses metaprogramming to add functionalities for securely hashing and storing passwords. It automatically adds attributes likepasswordandpassword_confirmationto the model, managed in-memory for security purposes.
Now, whenever you create a new user, the has_secure_password method will ensure the password is hashed using Bcrypt and stored in the password_digest field.
Next, let's implement the register action in the AuthenticationController, which will handle the creation of new users.
Here’s the code for the register action:
Explanation:
- The
registeraction creates a newUserobject with the provided parameters. - If the user is saved successfully, it returns a JSON response with a success message and a
createdstatus. - If there are errors, it returns a JSON response with the error messages and a
unprocessable_entitystatus. - The
user_paramsmethod ensures only permitted parameters (usernameandpassword) are allowed for user creation.
JWTs provide a robust solution for managing authentication. We'll create a token that can be sent to the client and used to verify user identity in subsequent requests. A token is a string of characters that represents a user's authentication credentials. In JWT, tokens contain user information like IDs and expiration dates, and they are securely signed to ensure authenticity. This allows users to authenticate and be recognized without the server having to store session data.
Here's how to set up the generate_token method in the AuthenticationController:
Explanation:
- The
generate_tokenmethod takes auser_idas an argument. - It uses the
JWT.encodemethod to create a token, encoding theuser_idwith a secret key (Rails.application.credentials.secret_key_base).
Finally, let’s implement the login action to authenticate a user and generate a JWT token if the credentials are valid.
Here’s the code for the login action:
Explanation:
- The
loginaction finds a user by the providedusername. - It checks if the user exists and if the
authenticatemethod verifies the password. - If successful, it generates a JWT token using the
generate_tokenmethod and returns it in the JSON response with aokstatus. - If the credentials are invalid, it returns an error message with an
unauthorizedstatus.
Lastly, register the new actions in the routes.rb file:
In this lesson, we covered:
- Creating the
Usermodel and securing passwords withhas_secure_password. - Implementing the
registeraction to create new users. - Setting up JWT-based authentication with the
generate_tokenmethod. - Implementing the
loginaction to authenticate users and provide a JWT token.
By achieving these tasks, you've secured your Ruby on Rails application using JWT for authentication. Now, move on to the practice exercises to further solidify your understanding. Great job!
