使用 React 和 FastAPI 进行登录验证
简介
在本教程中,我们将使用 React 和 FastApi 构建登录身份验证。这将有助于展示我们如何将这两个包用于登录身份验证过程,但在此之前,让我们看看 React 以及 FastApi 是什么。
什么是 FastApi
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于使用 Python 构建 API。它支持同步和异步操作、数据验证、身份验证和交互式 API 文档,所有这些都由 OpenAPI 提供支持。它具有令人兴奋的功能,例如:
什么是 React
React 是一个用户界面开发库。它可以通过与服务器/API 对话来构建全栈应用程序,并在客户端上作为 SPA(单页应用程序)运行。因为它可以胜任并且直接等同于 Angular 或 Vue 等框架,所以 React 经常被称为前端“框架”。
要求
-
Python 已安装。
-
Javascript基础知识。
-
React 基础知识。
-
有python知识是加分项。
安装 FastAPI
打开我们的终端并 cd 进入我们的project folder并写入以下内容:
mkdir backend
进入全屏模式 退出全屏模式
cd进入刚刚创建的文件夹并运行以下命令:
pip install fastapi
进入全屏模式 退出全屏模式
pip install "uvicorn[standard]"
进入全屏模式 退出全屏模式
pip install pyjwt
进入全屏模式 退出全屏模式
让我们稍后再继续构建我们的前端。
构建前端
让我们创建和应用并安装以下软件包:
npx create-react-app frontend
进入全屏模式 退出全屏模式
接下来我们安装以下软件包:
npm install axios react-router-dom
进入全屏模式 退出全屏模式
完成后,导航到src/index.js并导入BrowserRouter:
import { BrowserRouter } from "react-router-dom";
进入全屏模式 退出全屏模式
然后我们必须用这个替换React.StrictMode标签:
<BrowserRouter>
<App />
</BrowserRouter>,
进入全屏模式 退出全屏模式
现在转到app.js并导入:
import { Routes, Route } from "react-router-dom";
import Login from "./login";
import Profile from "./Profile";
进入全屏模式 退出全屏模式
在我们的return()中,让我们删除我们的 div 并将其替换为:
<div className ="App">
<Routes><!---what are routes in react-!>
<Route path="/" element = {<Login/>}/>
<Route path="/profile" element = {<Profile/>}/>
</Routes>
</div>
进入全屏模式 退出全屏模式
在这里,我们正在使用我们将很快创建的页面的路由。接下来让我们在src文件夹中创建一个名为Login.js的文件并粘贴:
export default function Login() {
return (
<>
<h1>login page</h1>
</>
);
}
进入全屏模式 退出全屏模式
我们还将创建另一个名为Profile.js的文件并将其粘贴:
export default function Profile() {
return (
<>
<h1>profile page</h1>
</>
);
}
进入全屏模式 退出全屏模式
现在让我们开始我们的应用程序:
npm start
进入全屏模式 退出全屏模式
[](https://res.cloudinary.com/practicaldev/image/fetch/s--1HpjrPa0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads .s3.amazonaws.com/uploads/articles/1b2a3tlgmltrfge0schq.PNG)
[](https://res.cloudinary.com/practicaldev/image/fetch/s--BAsNSBy4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads .s3.amazonaws.com/uploads/articles/33c6aeisc0u5788rsugn.PNG)
如您所见,我们的页面运行良好(还可以通过将/profile添加到 url 来检查配置文件页面)。现在我们已经完成了基础知识,让我们继续设置我们的身份验证。
让我们在src文件夹中创建一个名为Auth.js的新文件并粘贴:
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;
}
}
进入全屏模式 退出全屏模式
在这里,我们创建了变量来设置我们的令牌,获取并需要我们的令牌,所以让我们回到我们的app.js并导入我们的令牌:
import { RequireToken } from "./Auth";
进入全屏模式 退出全屏模式
我们将在app.js中添加一些东西。在我们的Route path="/profile"中,让我们通过添加我们的RequireToken来更改元素,因此我们的Route path="/profile"应该如下所示:
<Route
path="/profile"
element={
<RequireToken>
<Profile />
</RequireToken>
}
/>
进入全屏模式 退出全屏模式
当我们保存它并转到我们的应用程序时,我们看到我们的个人资料页面现在受到保护,只能使用有效令牌访问。现在让我们用我们的登录表单完成我们的登录页面。转到登录页面,清除所有内容,然后粘贴:
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>
</>
);
}
进入全屏模式 退出全屏模式
我们暂时停在那里。是时候在我们的后端工作了。
创建后端
现在让我们打开我们的后端文件夹,创建一个main.py文件并输入以下内容:
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"}
进入全屏模式 退出全屏模式
在这里,我们试图:
-
生成令牌。
-
定义
test user object以检查用户登录凭据 -
配置我们的
CORS以允许我们的 React 应用程序发送 POST 请求 -
使用
test_user对即将到来的数据进行检查。
现在我们已经完成了,让我们回到前端完成事情。前往 login.js 并将其替换为:
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>
);
}
进入全屏模式 退出全屏模式
我们还将对我们的profile.js进行更改,所以让我们打开它并粘贴:
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>
</>
);
}
进入全屏模式 退出全屏模式
我们完成了,让我们测试我们的应用程序。运行代码:
uvicorn main:app --reload
进入全屏模式 退出全屏模式
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--jiX8kdCS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads .s3.amazonaws.com/uploads/articles/3bga185xeiqrih0bse69.gif)
结论
在本教程中,我们了解了 FastApi 是什么以及 React 是什么。我们还学习了如何使用这些想法安装 FastApi 和 React 来构建我们的登录身份验证。这是github上的 repo 的链接。快乐编码!
更多推荐

所有评论(0)