Вход в систему React FastAPI Введение
В этом руководстве мы создадим систему входа в систему с помощью React и FastAPI Python.
FastAPI — это фреймворк Python. Это высокопроизводительная платформа, которую вы можете использовать для быстрой настройки вашего серверного приложения.
С другой стороны, React — это среда JavaScript, разработанная Facebook.
Кроме того, если вы из тех, кто лучше учится, просматривая видео, попробуйте этот Вход в React и FastAPI
Теперь давайте приступим к делу.
React и FastAPI Python — создание приложения React (интерфейс)
Давайте настроим новое приложение React. Я буду использовать JavaScript для этого урока. Вы можете отказаться от TypeScript, если хотите.
Откройте командную строку и выполните приведенные ниже команды.
npx create-react-app my-rasyue-app
// once the script runs sucessfully, run below.
cd my-rasyue-app
npm start
Теперь откройте предпочтительную IDE и откройте папку my-rasyue-app
.
Настройка нашего приложения React (интерфейс)
На высоком уровне наше приложение React должно:
- Иметь страницу входа и страницу профиля (защищенная страница, доступная только после входа в систему)
- Имейте кнопку выхода, которая очистит JWT, хранящийся в
localStorage
. - Страница входа будет иметь форму входа с двумя входами для имени пользователя и электронной почты.
- При отправке формы входа мы будем использовать axios для отправки запроса POST на сервер (FastAPI Python)
С этим покончено, давайте взламываем!
Создание страницы входа
Запустите команду ниже, чтобы установить react-router-dom
и axios
npm install react-router-dom@6
npm install axios
Откройте свой index.js
и вставьте следующее.
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from "react-router-dom"; import 'bootstrap/dist/css/bootstrap.min.css';
ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById('root') );
// If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();
Мы заключаем App
в ‹BrowserRouter
›, чтобы разрешить использование Routes
в приложении.
Теперь откройте свой App.js
и вставьте следующее.
import './App.css'; import { Route, Routes, } from "react-router-dom";
import Login from './Login.js' import Profile from './Profile.js'
function App() {
return ( <div className="App"> <Routes> <Route path="/" element={<Login />} /> <Route path="/profile" element={<Profile />} /> </Routes> </div> ); }
export default App;
Теперь нам нужно создать два новых файла Login.js
и Profile.js
.
Идите вперед и создайте эти два файла.
Внутри Login.js
вставьте следующее.
export default function Login(){
return( <> <div style = {{minHeight: 800, marginTop: 20 }}> <h1>Login Page</h1> </div> </> ) }
Внутри Profile.js
вставьте следующее.
export default function Profile(){
return( <> <div style = {{minHeight: 800, marginTop: 20 }}> <h1>Profile Page</h1> </div> </> ) }
Откройте браузер и откройте localhost:3000
У вас должно получиться что-то вроде этого.
На данный момент мы создали 2 новые страницы, Profile
и Login
. Мы также определили Routes
в нашем файле App.js
.
Ничего особенного.
Настройка аутентификации и создание защищенной страницы
Пришло время настроить нашу аутентификацию для React.
Создайте новый файл Auth.js
и вставьте следующее
import { Navigate , useLocation } from "react-router-dom";
export const setToken = (token) =>{
// set token in localStorage localStorage.setItem('rasyueToken', token)
}
export const fetchToken = (token) =>{
// fetch the token return localStorage.getItem('rasyueToken')
}
export function RequireToken({children}) {
let auth = fetchToken() let location = useLocation(); if (!auth) { return <Navigate to="/" state={{ from: location }} />; } return children; }
Откройте App.js
и замените следующим.
import './App.css'; import { Route, Routes, } from "react-router-dom";
import Login from './Login.js' import Profile from './Profile.js'
import {RequireToken} from './Auth.js'
function App() {
return ( <div className="App"> <Routes> <Route path="/" element={<Login />} /> <Route path="/profile" element={ <RequireToken> <Profile /> </RequireToken> } /> </Routes> </div> ); }
export default App;
Чтобы объяснить, что мы сделали, мы сначала создали новый файл Auth.js
и внутри него мы определили 3 функции, а именно, setToken
, fetchToken
и RequireToken
setToken
и fetchToken
предназначены для установки и извлечения элемента, который мы сохранили в localStorage
.
Если вы не знакомы с localStorage, предлагаю вам ознакомиться с ними здесь
RequireToken
используется в Route
в App.js
. Функция получит дочерний путь и определит, разрешен ли пользователю доступ к пути или нет.
Это шаг к тому, чтобы сделать страницу защищенной, в данном случае мы делаем защищенной страницу Profile
.
Если токен недоступен, пользователь не сможет получить к нему доступ.
Давайте закончим последнюю часть нашего приложения React для входа в систему.
React FastAPI — заполнение формы входа
Откройте свой Login.js
и вставьте следующее.
import {useState} from 'react' import {setToken, fetchToken} from './Auth.js' import {useNavigate} from "react-router-dom"; const axios = require('axios');
export default function Login(){
const navigate = useNavigate(); const [username, setUsername] = useState(''); const [password, setPassword] = useState('');
const login = () =>{
if(username === '' && password === ''){
return
}else{
console.log('axios') axios.post('http://localhost:8000/login', { username: username, password: password }) .then(function (response) {
if(response.data.token){ setToken(response.data.token) navigate("/profile"); } }) .catch(function (error) {
console.log(error, 'error');
});
} }
return( <> <div style = {{minHeight: 800, marginTop: 20 }}> <h1>Home Page</h1>
<div style = {{marginTop: 50 }} > { fetchToken() ? ( <p>You are logged in!</p> ) : ( <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> </> ) }
Обновите, и ваша страница будет выглядеть примерно так.
И, наконец, откройте свой Profile.js
и замените на следующие.
import {useNavigate} from "react-router-dom";
export default function Profile(){
const navigate = useNavigate();
const signOut = () => {
localStorage.removeItem('rasyueToken') navigate("/"); }
return( <> <div style = {{minHeight: 800, marginTop: 20 }}> <h1>Profile Page</h1>
<p>Hi, this is your profile</p>
<div> <button type = 'button' onClick= {signOut}>Sign Out</button> </div> </div> </> ) }
Если вы протестируете свою систему входа прямо сейчас, она пока не будет работать, нам все еще нужно создать наш сервер.
Давайте создадим наше серверное приложение FastAPI.
React и FastAPI Python — создание приложения FastAPI (бэкэнд)
Давайте настроим наше приложение FastAPI.
Во-первых, убедитесь, что на вашем компьютере установлен Python.
В этом уроке я буду использовать Anaconda и Pycharm, потому что это дает больше контроля над модулями Python, но вам не нужно загружать и Anaconda, и Pycharm.
Просто установка Python и использование любой другой IDE должны работать.
Создайте новую папку и назовите ее как угодно, а внутри создайте новое имя main.py
Прежде чем мы сможем использовать FastAPI, нам нужно сначала установить его через pip
. Запустите команду ниже, чтобы установить его.
pip install fastapi
pip install "uvicorn[standard]"
pip install pyjwt
Вход в React FastAPI — создание первой страницы Hello World
Теперь в main.py
вставьте следующее.
from fastapi import FastAPI
app = FastAPI()
@app.get("/") def read_root(): return {"Hello": "World"}
Запустите приложение FastAPI с помощью uvicorn main:app --reload
У вас должно получиться что-то вроде этого.
Следующим шагом является определение конечной точки, которая будет обрабатывать запрос на вход от внешнего приложения React.
Конечная точка также должна генерировать токен JWT и взаимодействовать с базой данных MongoDB.
React FastAPI Login — создание конечной точки входа
Откройте свой main.py
и вставьте следующее.
from fastapi import FastAPI from typing import Optional from pydantic import BaseModel
app = FastAPI()
class LoginItem(BaseModel): email: str password: str
@app.get("/") def read_root(): return {"Hello": "World"}
@app.post("/login") async def login_user(login_item: LoginItem): return login_item
Как вы можете видеть выше, мы добавили еще одну конечную точку /login
, которая принимает только запросы на публикацию, которые приходят вместе с вводом объекта login_item
.
Тип LoginItem
был определен, чтобы убедиться, что входные данные почтового запроса состоят только из email
и password
.
Если бы мы протестировали конечную точку с помощью Postman, мы бы получили что-то вроде этого.
React FastAPI Login — изменение конечной точки входа для создания JWT
Теперь, когда у нас работает конечная точка login
, следующим шагом будет реализация функции для создания JWT.
Откройте свой main.py
и замените следующим.
from fastapi import FastAPI
import jwt from pydantic import BaseModel from fastapi.encoders import jsonable_encoder
SECRET_KEY = "my_secret_key" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 800
dummy_user = { "username": "rasyue", "password": "rasyuepassword", }
app = FastAPI()
class LoginItem(BaseModel): username: str password: str
@app.get("/") def read_root(): return {"Hello": "World"}
@app.post("/login") async def login_user(login_item: LoginItem):
data = jsonable_encoder(login_item) if dummy_user['username'] == data['username'] and dummy_user['username'] == data['username']: encoded_jwt = jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM) return {'token': encoded_jwt } else: return {'message': 'Login failed'}
Чтобы объяснить вышесказанное, во-первых, мы добавили в микс модуль JWT, а также the jsonable_encoder
.
Затем мы определяем SECRET_KEY
, ALGORITHM
и ACCESS_TOKEN_EXPIRE_MINUTES
, которые мы будем использовать позже, когда захотим сгенерировать наш токен.
Затем мы определяем dummy_user
, который является объектом, в котором хранятся наши учетные данные. Обратите внимание, что я изменил email
в классе LoginItem
на username
.
В реальном приложении мы должны использовать данные, которые поступают из базы данных, когда пользователь входит в систему, но для простоты можно использовать жестко закодированные учетные данные.
Идите вперед и протестируйте свою конечную точку с помощью Postman.
Это все, что касается нашего бэкэнда.
Тестирование нашей формы входа
Наконец, все настроено, давайте протестируем нашу систему входа в систему.
Страница Profile
защищена, без токена вы не сможете получить к ней доступ. Попробуйте выйти и посмотреть, что произойдет с токеном.
Конец
Вот и все для этого урока.
Если вам интересно узнать больше об аналогичном руководстве, ознакомьтесь с этим руководством, которое я написал, которому вы можете легко следовать, Создание системы входа в Angular и FastAPI
Больше контента на blog.devgenius.io.