DEV Community

NJOKU SAMSON EBERE
NJOKU SAMSON EBERE

Posted on • Updated on

React Authentication - LOGIN

This tutorial is a continuation from my last article. We are still learning how to build an authentication system with react. Check out this article to bring you up to speed.

If you want to follow this tutorial step by step, please get the starter code from last article here

Login

Now we turn attention to the Login.js file. If you are coming from the last article, most of the following steps will be familiar.

  • Set initial states for email, password and login

  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [login, setLogin] = useState(false);

Enter fullscreen mode Exit fullscreen mode
  • Set a name and value attribute for the email and password input fields. This is mine:

{/* email */}
        <Form.Group controlId="formBasicEmail">
          <Form.Label>Email address</Form.Label>
          <Form.Control
            type="email"
            name="email"
            value={email}
            placeholder="Enter email"
          />
        </Form.Group>

        {/* password */}
        <Form.Group controlId="formBasicPassword">
          <Form.Label>Password</Form.Label>
          <Form.Control
            type="password"
            name="password"
            value={password}
            placeholder="Password"
          />
        </Form.Group>

Enter fullscreen mode Exit fullscreen mode

At this point, you will notice that you can no longer type into the Login Form fields. This is because we have not set the field to update from the previous state to the current state. Let's do that

  • Add onChange={(e) => setEmail(e.target.value)} and onChange={(e) => setPassword(e.target.value)} to the email and password input fields respectively. This is mine:

       {/* email */}
        <Form.Group controlId="formBasicEmail">
          <Form.Label>Email address</Form.Label>
          <Form.Control
            type="email"
            name="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="Enter email"
          />
        </Form.Group>

        {/* password */}
        <Form.Group controlId="formBasicPassword">
          <Form.Label>Password</Form.Label>
          <Form.Control
            type="password"
            name="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            placeholder="Password"
          />
        </Form.Group>

Enter fullscreen mode Exit fullscreen mode

Now you can type into the form fields because it is now updating the state to the content you type in

  • Add onSubmit={(e)=>handleSubmit(e)} and onClick={(e)=>handleSubmit(e)} to the form and button element respectively. The onSubmit enables form submission using the Enter key while the onClick enables form submission by clicking the button. Now the form looks like this:

      <Form onSubmit={(e)=>handleSubmit(e)}>
        {/* email */}
        <Form.Group controlId="formBasicEmail">
          <Form.Label>Email address</Form.Label>
          <Form.Control
            type="email"
            name="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="Enter email"
          />
        </Form.Group>

        {/* password */}
        <Form.Group controlId="formBasicPassword">
          <Form.Label>Password</Form.Label>
          <Form.Control
            type="password"
            name="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            placeholder="Password"
          />
        </Form.Group>

        {/* submit button */}
        <Button
          variant="primary"
          type="submit"
          onClick={(e) => handleSubmit(e)}
        >
          Login
        </Button>
      </Form>

Enter fullscreen mode Exit fullscreen mode
  • To test if this is working, create the following function just before the return line

const handleSubmit = (e) => {
    // prevent the form from refreshing the whole page
    e.preventDefault();
    // make a popup alert showing the "submitted" text
    alert("Submited");
  }

Enter fullscreen mode Exit fullscreen mode

If you click the button or hit the Enter Key, this should be your result:

Testing the handleSubmit function

Building out the handleSubmit function

  • Now remove the alert statement from the handleSubmit function

  • Install Axios if you are not coming from the previous article. We will be using axios to call the API or connect the frontend to the backend as the case maybe.


npm i axios

Enter fullscreen mode Exit fullscreen mode
  • Import axios at the top of the file like so:

import axios from "axios";

Enter fullscreen mode Exit fullscreen mode
  • In the handleSubmit function, let's build out the configuration needed for axios to successfully connect our frontend to the backend.

// set configurations
    const configuration = {
      method: "post",
      url: "https://nodejs-mongodb-auth-app.herokuapp.com/login",
      data: {
        email,
        password,
      },
    };

Enter fullscreen mode Exit fullscreen mode

The method tells how our data will be processed, url is the endpoint through which the API function will be accessed and data contains all the input or request body that the backend is expecting. Hopefully that is clear enough.

  • Having the configurations setup, let's now make the call. The API call is just a one-line statement. Here:

axios(configuration)

Enter fullscreen mode Exit fullscreen mode

With that, the API call has been completed. However, we need to be sure if it actually succeeded or not. And maybe show the result to our users. So to fix that, we will use a then...catch... block

  • Now we have this:

    // make the API call
    axios(configuration)
    .then((result) => {console.log(result);})
    .catch((error) => {console.log(error);})

Enter fullscreen mode Exit fullscreen mode

We are logging to the console just for testing purposes

  • Now try logging in a new user and check the console for the result. Mine was successful. See below:

Alt Text

Of course we will not direct our users to the console to check for the result of their login attempt. So let's find a way to communicate to the user

  • Replace the code with the following code:

    // make the API call
    axios(configuration)
      .then((result) => {
        setLogin(true);
      })
      .catch((error) => {
        error = new Error();
      });

Enter fullscreen mode Exit fullscreen mode

By setting login to true, we can now tell when the login process is completed. So let's tell the user

  • Add the following code in the Form element

      {/* display success message */}
        {login ? (
          <p className="text-success">You Are Logged in Successfully</p>
        ) : (
          <p className="text-danger">You Are Not Logged in</p>
        )}

Enter fullscreen mode Exit fullscreen mode

The code is a conditional statement to display success message when the login is true. Now let's give it a try

This is mine:

Alt Text

If you are getting same result as mine, then you did it!!!

You are awesome

Conclusion

We began this tutorial from where we left off last time. We have see how to log in a user that we have registered already.

All codes are here

Next, we will look at how to extract our login token and use it to access endpoints or routes that are protected.

Just stick around

Top comments (6)

Collapse
 
khorne07 profile image
Khorne07

Great article. Just an small opinion. In the form you explained why you call the handleSubmit in both, the form and the submit button. I usually only call it in the form and the button with just defining the button prop type="submit" and the default event will be submit the form using the handler defined in the onSubmit prop of the form.

Collapse
 
ebereplenty profile image
NJOKU SAMSON EBERE

Thank you very much Khorne for your comment. It is cool too.

Collapse
 
biyiemmy profile image
Adebiyi Emmanuel

Having this error when I pressed on Register button
:
Access to XMLHttpRequest at 'nodejs-mongodb-auth-app.herokuapp....' from origin 'localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
xhr.js:247 POST nodejs-mongodb-auth-app.herokuapp.... net::ERR_FAILED
dispat

Collapse
 
ebereplenty profile image
NJOKU SAMSON EBERE

Thank you for reading ❤️

Collapse
 
eljeffe profile image
elJeffe

Great tutorial! Just wondering how do you redirect the user to an (authenticated) url? Because if I use useHistory().push('/auth'); in the button click it won't work as the state is still false.

Collapse
 
ebereplenty profile image
NJOKU SAMSON EBERE

I will be going in detail on this in the next article. It will be out next week.

Meanwhile, you can use cookies to make the Auth token available in all of your pages. Then use token to make the API call

We also have the concept of protected routes in React where only authenticated users can access such routes.