Login Authentication With React And FastAPI

Introduction

In this tutorial, we’ll be building a login authentication using React and FastApi. This will help show how we can use both packages for a login authentication process but before that, let’s take at React and also what FastApi i…


This content originally appeared on DEV Community and was authored by oyedeletemitope

Introduction

In this tutorial, we'll be building a login authentication using React and FastApi. This will help show how we can use both packages for a login authentication process but before that, let's take at React and also what FastApi is.

What is FastApi

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python. It supports both synchronous and asynchronous actions, as well as data validation, authentication, and interactive API documentation, all of which are powered by OpenAPI. It comes with exciting features like:

What is React

React is a user interface development library. It can construct full-stack apps by talking with a server/API and operates as an SPA (single page app) on the client. Because it is competent and directly equivalent to frameworks like Angular or Vue, React is frequently referred to as a frontend "framework".

Requirements

  • Python installed.
  • Basic knowledge of Javascript.
  • Basic Knowledge of React.
  • Knowledge on python is a plus.

Installing FastAPI

open up our terminal and cd into our project folder and write the following:

mkdir backend

cd into the just created folder and run the following:

pip install fastapi
pip install "uvicorn[standard]"
pip install pyjwt

let's leave that for later and proceed with building our frontend.

Building The Frontend

let's create and app and install the following packages:

npx create-react-app frontend

Next we install the following packages:

npm install axios react-router-dom

After we've done that, navigate to src/index.js and import BrowserRouter :

import { BrowserRouter } from "react-router-dom";

We then have to replace the React.StrictMode tags with this:

<BrowserRouter>
    <App />
  </BrowserRouter>,

Now head over to app.js and import this:

import { Routes, Route } from "react-router-dom";
import Login from "./login";
import Profile from "./Profile";

Inside our return() lets delete our div and replace it with this:

  <div className ="App">
    <Routes><!---what are routes in react-!>
      <Route path="/" element = {<Login/>}/>
      <Route path="/profile" element = {<Profile/>}/>
    </Routes>
    </div>

Here we are using the routes to the pages we'll be creating shortly. Next let's create a file called Login.js in our src folder and paste this:

export default function Login() {
  return (
    <>
      <h1>login page</h1>
    </>
  );
}

We'll also create another file called Profile.js and paste this:

export default function Profile() {
  return (
    <>
      <h1>profile page</h1>
    </>
  );
}

Now let's start our application:

npm start

login

profile

As you can see, our page is working fine (also check the profile page by adding /profile to the url). Now that we're done with basics, let's proceed to setting up our authentication.

Let's create a new file in our src folder called Auth.js and paste this:

import { useLocation,Navigate } from "react-router-dom"

export const setToken = (token)=>{

    localStorage.setItem('temitope', token)// make up your own token
}

export const fetchToken = (token)=>{

    return localStorage.getItem('temitope')
}

export function RequireToken({children}){

    let auth = fetchToken()
    let location = useLocation()

    if(!auth){

        return <Navigate to='/' state ={{from : location}}/>;
    }

    return children;
}
}

Here we created variables setting our token, fetching and also requiring our token, so let's go back to our app.js and import our token:

import { RequireToken } from "./Auth";

We'll be adding some things in our app.js. In our Route path="/profile" let's make changes to the element by adding our RequireToken so our Route path="/profile" should look like this:

<Route
  path="/profile"
  element={
    <RequireToken>
      <Profile />
    </RequireToken>
  }
/>

When we save this and go to our app we would see that our profile page is now protected and can only be accessed with a valid token. Now let's finish our login page with our login form. head over to login page clear all and paste this:

import { useNavigate } from "react-router";
import { fetchToken } from "./Auth";

export default function Login() {
  const navigate = useNavigate();
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  //check to see if the fields are not empty
  const login = () => {
    if ((username == "") & (password == "")) {
      return;
    } else {
      // make api call to our backend. we'll leave this for later
    }
  };

  return (
    <>
      <div style={{ minHeight: 800, marginTop: 30 }}>
        <h1>login page</h1>
        <div style={{ marginTop: 30 }}>
          {fetchToken() ? (
            <p>you are logged in</p>
          ) : (
            <div>
              <form>
                <label style={{ marginRight: 10 }}>Input Username</label>
                <input
                  type="text"
                  onChange={(e) => setUsername(e.target.value)}
                />

                <label style={{ marginRight: 10 }}>Input Password</label>
                <input
                  type="text"
                  onChange={(e) => setPassword(e.target.value)}
                />

                <button onClick={login}>Login</button>
              </form>
            </div>
          )}
        </div>
      </div>
    </>
  );
}

We'll be pausing there for now. It's time to work on our backend.

Creating the backend

Now lets open up our backend folder, create a main.py file and input the following:

from fastapi import FastAPI
from pydantic import BaseModel
import jwt
from pydantic import BaseModel
from fastapi.encoders import jsonable_encoder
from fastapi.middleware.cors import CORSMiddleware


SECERT_KEY = "YOUR_FAST_API_SECRET_KEY"
ALGORITHM ="HS256"
ACCESS_TOKEN_EXPIRES_MINUTES = 800

test_user = {
   "username": "temitope",
    "password": "temipassword",

}

app = FastAPI()

origins = {
    "http://localhost",
    "http://localhost:3000",
}

app.add_middleware(
   CORSMiddleware,
    allow_origins = origins,
    allow_credentials =True,
    allow_methods = ["*"],
    allow_headers= ["*"],
)

class LoginItem(BaseModel):
    username: str
    password: str

    @app.get("/")
    def read_root():
     return {"Hello": "World"}

@app.post("/login")
async def user_login(loginitem:LoginItem):


    data = jsonable_encoder(loginitem)

    if data['username']== test_user['username'] and data['password']== test_user['password']:

        encoded_jwt = jwt.encode(data, SECERT_KEY, algorithm=ALGORITHM)
        return {"token": encoded_jwt}

    else:
        return {"message":"login failed"}

Here we are trying to:

  • Generate a token.
  • Defining a test user object to check against the user login credentials
  • Configuring our CORS to allow our React app to send POST requests
  • Running a check with the coming data with test_user.

Almost done now that we're done, let's go back to the fronted and finish things up. head over to login.js and replace with this:

import { useNavigate } from "react-router";
import { fetchToken, setToken } from "./Auth";
import { useState } from "react";
import axios from "axios";

export default function Login() {
  const navigate = useNavigate();
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  //check to see if the fields are not empty
  const login = () => {
    if ((username == "") & (password == "")) {
      return;
    } else {
      // make api call to our backend. we'll leave thisfor later
      axios
        .post("http://localhost:8000/login", {
          username: username,
          password: password,
        })
        .then(function (response) {
          console.log(response.data.token, "response.data.token");
          if (response.data.token) {
            setToken(response.data.token);
            navigate("/profile");
          }
        })
        .catch(function (error) {
          console.log(error, "error");
        });
    }
  };

  return (
    <div style={{ minHeight: 800, marginTop: 30 }}>
      <h1>login page</h1>
      <div style={{ marginTop: 30 }}>
        {fetchToken() ? (
          <p>you are logged in</p>
        ) : (
          <div>
            <form>
              <label style={{ marginRight: 10 }}>Input Username</label>
              <input
                type="text"
                onChange={(e) => setUsername(e.target.value)}
              />

              <label style={{ marginRight: 10 }}>Input Password</label>
              <input
                type="text"
                onChange={(e) => setPassword(e.target.value)}
              />

              <button type="button" onClick={login}>
                Login
              </button>
            </form>
          </div>
        )}
      </div>
    </div>
  );
}

We'll also make changes to our profile.js so let's open it up and paste this:

import { useNavigate } from "react-router";
export default function Profile() {
  const navigate = useNavigate();

  const signOut = () => {
    localStorage.removeItem("temitope");
    navigate("/");
  };

  return (
    <>
      <div style={{ marginTop: 20, minHeight: 700 }}>
        <h1>Profile page</h1>
        <p>Hello there, welcome to your profile page</p>

        <button onClick={signOut}>sign out</button>
      </div>
    </>
  );
}

We're done, let' test our app . Run the code:

uvicorn main:app --reload

finish

Conclusion

In tutorial, we looked at what FastApi is and also what React is. We also learned how to install FastApi as well as React using these ideas to build our login authenication. Here's a link to the repo on github. Happy coding!!!


This content originally appeared on DEV Community and was authored by oyedeletemitope


Print Share Comment Cite Upload Translate Updates
APA

oyedeletemitope | Sciencx (2021-12-24T20:17:43+00:00) Login Authentication With React And FastAPI. Retrieved from https://www.scien.cx/2021/12/24/login-authentication-with-react-and-fastapi/

MLA
" » Login Authentication With React And FastAPI." oyedeletemitope | Sciencx - Friday December 24, 2021, https://www.scien.cx/2021/12/24/login-authentication-with-react-and-fastapi/
HARVARD
oyedeletemitope | Sciencx Friday December 24, 2021 » Login Authentication With React And FastAPI., viewed ,<https://www.scien.cx/2021/12/24/login-authentication-with-react-and-fastapi/>
VANCOUVER
oyedeletemitope | Sciencx - » Login Authentication With React And FastAPI. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/12/24/login-authentication-with-react-and-fastapi/
CHICAGO
" » Login Authentication With React And FastAPI." oyedeletemitope | Sciencx - Accessed . https://www.scien.cx/2021/12/24/login-authentication-with-react-and-fastapi/
IEEE
" » Login Authentication With React And FastAPI." oyedeletemitope | Sciencx [Online]. Available: https://www.scien.cx/2021/12/24/login-authentication-with-react-and-fastapi/. [Accessed: ]
rf:citation
» Login Authentication With React And FastAPI | oyedeletemitope | Sciencx | https://www.scien.cx/2021/12/24/login-authentication-with-react-and-fastapi/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.