Install Fastapi
https://github.com/tiangolo/fastapi
pip install fastapi
C:\fastAPI\react>pip install fastapi
C:\fastAPI\react>pip install "uvicorn[standard]"
Create main.py
react/main.py
#react/main.py from fastapi import FastAPI import jwt #pip install pyjwt https://pypi.org/project/PyJWT/ from pydantic import BaseModel from fastapi.encoders import jsonable_encoder SECRET_KEY = "cairocoders123456789" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 800 dummy_user = { "username": "cairocoders", "password": "123456ednalan", } from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add_middleware( CORSMiddleware, allow_methods=["*"], allow_headers=["*"], allow_credentials=True, allow_origins=["http://localhost:3000"]) class Loginclass(BaseModel): username: str password: str @app.get("/") def read_root(): return {"Hello": "World"} @app.post("/login") async def login_user(login_item: Loginclass): data = jsonable_encoder(login_item) if dummy_user['username'] == data['username'] and dummy_user['password'] == data['password']: encoded_jwt = jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM) return {'token': encoded_jwt } else: return {'message': 'Login failed'}
install PyJWT
https://github.com/jpadilla/pyjwt
pip install PyJWT
C:\fastAPI\react>pip install PyJWT
Rn C:\fastAPI\react>uvicorn main:app --reload
http://127.0.0.1:8000/docs
React JS
Create Project
C:\react-js>npx create-react-app myreactdev
Run
C:\react-js\myreactdev> npm start
Install React Router Dom
https://www.npmjs.com/package/react-router-dom
C:\react-js\myreactdev>npm i react-router-dom --save
Install Axios
https://www.npmjs.com/package/axios
C:\react-js\myreactdev>npm install axios --save
C:\react-js\myreactdev\src\App.js
//C:\react-js\myreactdev\src\App.js import React, { } from 'react'; import './App.css'; import {BrowserRouter, Routes, Route, Link} from 'react-router-dom'; import Login from './components/Login.js' import Profile from './components/Profile.js' import {RequireToken} from './components/Auth.js' function App() { return ( <div className="vh-100 gradient-custom"> <div className="container"> <h1 className="page-header text-center">React and FastAPI Login with PyJWT token authentication</h1> <BrowserRouter> <p><Link to="/" className="btn btn-success">Login</Link> | <Link to="profile" className="btn btn-success">Profile</Link> </p> <Routes> <Route path="/" element={<Login />} /> <Route path="/profile" element={ <RequireToken> <Profile /> </RequireToken> } /> </Routes> </BrowserRouter> </div> </div> ); } export default App;open index.html C:\react-js\myreactdev\public\index.html add bootstrap 5 <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"/>
Login.js
C:\react-js\myreactdev\src\components\Login.js
//C:\react-js\myreactdev\src\components\Login.js import React, { useState } from 'react'; import axios from 'axios'; import {useNavigate} from "react-router-dom"; import {setToken, fetchToken} from './Auth.js' export default function Login(){ const navigate = useNavigate(); const [username,setUsername] = useState(''); const [password,setPassword] = useState(''); const handleSubmit = () => { if(username.length === 0){ alert("Username has left Blank!"); } else if(password.length === 0){ alert("password has left Blank!"); } else{ console.log('axios') axios.post('http://localhost:8000/login', { username: username, password: password }) .then(function (response) { console.log(response); //console.log(response.data); alert(response.data["message"]) if (response.data["message"]=="Login failed") { alert("Login failed"); }else { if(response.data.token){ setToken(response.data.token) navigate("/profile"); } } }) .catch(function (error) { console.log(error, 'error'); }); } } return ( <div> <div className="mask d-flex align-items-center h-100 gradient-custom-3"> <div className="container h-100"> <div className="row d-flex justify-content-center align-items-center h-100"> <div className="col-12 col-md-9 col-lg-7 col-xl-6"> <div className="card"> <div className="card-body p-5"> { fetchToken() ? ( <p>You are logged in!</p> ) : ( <p>Login Account!</p> ) } <form> <div className="form-outline mb-4"> <label className="form-label">Your User Name</label> <input type="text" className="form-control form-control-lg" name="username" id="username" value={username} onChange={(e) => setUsername(e.target.value)} /> </div> <div className="form-outline mb-4"> <label className="form-label">Your Password</label> <input type="text" className="form-control form-control-lg" name="password" id="password" value={password} onChange={(e) => setPassword(e.target.value)} /> </div> <div className="d-flex justify-content-center"> <input type="button" className="btn btn-success btn-lg" name="submit" id="submit" value="Login" onClick={handleSubmit} /> </div> </form> </div> </div> </div> </div> </div> </div> </div> ); }Profile.js
C:\react-js\myreactdev\src\components\Profile.js
//C:\react-js\myreactdev\src\components\Profile.js import React, { } from "react"; import {useNavigate} from "react-router-dom"; export default function Profile(){ const navigate = useNavigate(); const signOut = () => { localStorage.removeItem('cairocodersToken') navigate("/"); } return( <> <div style = {{minHeight: 800, marginTop: 20 }}> <h1>Profile Page</h1> <p>Hi, this is your profile</p> <div> <button type = 'button' className="btn btn-success btn-lg" onClick= {signOut}>Sign Out</button> </div> </div> </> ) }Auth.js
C:\react-js\myreactdev\src\components\Auth.js
//C:\react-js\myreactdev\src\components\Auth.js import React, { } from "react"; import { Navigate , useLocation } from "react-router-dom"; export const setToken = (token) =>{ // set token in localStorage localStorage.setItem('cairocodersToken', token) } export const fetchToken = (token) =>{ // fetch the token return localStorage.getItem('cairocodersToken') } export function RequireToken({children}) { let auth = fetchToken() let location = useLocation(); if (!auth) { return <Navigate to="/" state={{ from: location }} />; } return children; }react-js\myreactdev\src\App.css
//react-js\myreactdev\src\App.css .card { border-radius: 15px; } .gradient-custom { background: linear-gradient(to bottom right, rgba(240, 147, 251, 1), rgba(245, 87, 108, 1)); }Run C:\react-j\myreactdev>npm start
http://localhost:3000/