DEV Community

Cover image for Authentication using React and Ruby on Rails: creating a login, staying logged in, and logging out
ArmandeepKaur
ArmandeepKaur

Posted on

Authentication using React and Ruby on Rails: creating a login, staying logged in, and logging out

In this post, I will explain how to create a login page using a Ruby on Rails backend and React frontend.

Add sessions and cookies to application.rb

In config/application.rb, add the following code:

    config.middleware.use ActionDispatch::Cookies
    config.middleware.use ActionDispatch::Session::CookieStore

    # Use SameSite=Strict for all cookies to help protect against CSRF
    config.action_dispatch.cookies_same_site_protection = :strict
Enter fullscreen mode Exit fullscreen mode

Update application_controller.rb

In app/controllers/application.rb, add the following code:

include ActionController::Cookies
Enter fullscreen mode Exit fullscreen mode

This allows all of our controllers to work with the cookies. After adding the above code, your application_controller.rb should look like this:

class ApplicationController < ActionController::API
  include ActionController::Cookies
end
Enter fullscreen mode Exit fullscreen mode

Create a sessions_controller.rb file

One can create a sessions_controller.rb file by entering the following code in the terminal. The command utilizes a rails generator to create a sessions controller.

rails g controller Sessions
Enter fullscreen mode Exit fullscreen mode

Create a login path

In config/routes.rb, add the following route:

post "/login", to: "sessions#create"
Enter fullscreen mode Exit fullscreen mode

Create a login request on the frontend

function Login(){

    const [username, setUsername] = useState("")
    const [password, setPassword] = useState("")


    function handlSubmit(e){
        e.preventDefault()
        const formData = {
            username: username, 
            password: password
        }
        fetch("/login", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify(formData),
          })
            .then((r) => r.json())
            .then(navigate("/"));
        }

     return (
        <div className="login-div">
            <form  className="form" onSubmit={handlSubmit}>
                <input 
                    id="username"
                    type="text"
                    onChange={(e) =>   setUsername(e.target.value)}
                    value={username}
                    placeholder="username"/>
                <input 
                    id="password"
                    type="password"
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                    placeholder="password"
                />
                <input 
                type="submit"
                value="Login"
                className="login_buttons"
                />
                <h3>OR</h3>
                <button onClick={handleAccount} className="login_buttons">Create Account</button>
            </form>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

The above code create a login form and creates a post request for the login path defined in config/routes.rb. These steps will ensure that a person can login using their username and password.

Remain logged in

To remain logged in, one must define a route that fetches the data for the user who matches the session id created in the last step.

In config/routes.rb, define the following route:

get "/me", to: "users#show"
Enter fullscreen mode Exit fullscreen mode

In your user_controller.rb, create a show method that finds a user with the same session created in the login.

class UsersController < ApplicationController
  def show
    user = User.find_by(id: session[:user_id])
    if user
      render json: user
    else
      render json: { error: "Not authorized" }, status: :unauthorized
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

Finally, create a get request in React that fetches the data for that specific user.

 const [me, setMe] = useState([])


  useEffect(() => {
    fetch("/me")
    .then((resp) => resp.json())
    .then((info) => setMe(info))
  },[])
Enter fullscreen mode Exit fullscreen mode

Logging out

In config/routes.rb, create the following route:

delete "/logout", to: "sessions#destroy"
Enter fullscreen mode Exit fullscreen mode

In sessions controller, define a delete method:

def destroy
  session.delete :user_id
  head :no_content
end
Enter fullscreen mode Exit fullscreen mode

In React, create a delete request like the following:

function logout(){
  fetch("/logout", {
  method: "DELETE",
  }).then(navigate("/login"));
}
Enter fullscreen mode Exit fullscreen mode

In Conclusion

Creating a login page using ruby and rails and react can be very simple using the above code. One must define the correct routes, define the correct methods in the right controller, and create the correct requests on the frontend.

Top comments (0)