Sarting auth implementation in front
This commit is contained in:
@@ -4,7 +4,7 @@ import uuid
|
||||
from beanie import PydanticObjectId
|
||||
from fastapi import Depends
|
||||
from fastapi_users import UUIDIDMixin, BaseUserManager, FastAPIUsers, schemas
|
||||
from fastapi_users.authentication import AuthenticationBackend, BearerTransport
|
||||
from fastapi_users.authentication import AuthenticationBackend, BearerTransport, CookieTransport
|
||||
from fastapi_users.authentication.strategy import AccessTokenDatabase, DatabaseStrategy
|
||||
from fastapi_users_db_beanie.access_token import BeanieBaseAccessTokenDocument, BeanieAccessTokenDatabase
|
||||
from httpx_oauth.clients.google import GoogleOAuth2
|
||||
@@ -19,7 +19,8 @@ discord_oauth_client = DiscordOAuth2(os.getenv("DISCORD_CLIENT_ID"), os.getenv("
|
||||
|
||||
TOKEN_LIFETIME = 3600
|
||||
|
||||
bearer_transport = BearerTransport(tokenUrl="auth/login")
|
||||
# bearer_transport = BearerTransport(tokenUrl="auth/login")
|
||||
cookie_transport = CookieTransport(cookie_name="rpkapiusersauth")
|
||||
|
||||
|
||||
class AccessToken(BeanieBaseAccessTokenDocument):
|
||||
@@ -44,10 +45,7 @@ async def get_user_manager(user_db=Depends(get_user_db)):
|
||||
yield UserManager(user_db)
|
||||
|
||||
|
||||
auth_backend = AuthenticationBackend(
|
||||
name="db",
|
||||
transport=bearer_transport,
|
||||
get_strategy=get_database_strategy,
|
||||
auth_backend = AuthenticationBackend(name="db", transport=cookie_transport, get_strategy=get_database_strategy,
|
||||
)
|
||||
|
||||
fastapi_users = FastAPIUsers[User, PydanticObjectId](get_user_manager, [auth_backend])
|
||||
|
||||
@@ -2,7 +2,7 @@ services:
|
||||
api:
|
||||
build:
|
||||
context: ./api
|
||||
#image: roleplay-contracts-api-dev
|
||||
image: roleplay-contracts-api-dev
|
||||
env_file: "./.env"
|
||||
restart: always
|
||||
ports:
|
||||
@@ -16,21 +16,21 @@ services:
|
||||
- "traefik.http.routers.back.rule=PathPrefix(`/api/v1/`)"
|
||||
- "traefik.http.services.back.loadbalancer.server.port=8000"
|
||||
|
||||
# gui:
|
||||
# build:
|
||||
# context: ./gui
|
||||
# image: roleplay-contracts-gui-dev
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "4200:4200"
|
||||
# volumes:
|
||||
# - ./gui/rpk-gui/src:/app/src
|
||||
# - ./gui/rpk-gui/public:/app/public
|
||||
# labels:
|
||||
# - "traefik.enable=true"
|
||||
# - "traefik.http.routers.front.entrypoints=web"
|
||||
# - "traefik.http.routers.front.rule=PathPrefix(`/`)"
|
||||
# - "traefik.http.services.front.loadbalancer.server.port=4200"
|
||||
gui:
|
||||
build:
|
||||
context: ./gui
|
||||
image: roleplay-contracts-gui-dev
|
||||
restart: always
|
||||
ports:
|
||||
- "4200:4200"
|
||||
volumes:
|
||||
- ./gui/rpk-gui/src:/app/src
|
||||
- ./gui/rpk-gui/public:/app/public
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.front.entrypoints=web"
|
||||
- "traefik.http.routers.front.rule=PathPrefix(`/`)"
|
||||
- "traefik.http.services.front.loadbalancer.server.port=4200"
|
||||
|
||||
proxy:
|
||||
image: traefik:latest
|
||||
|
||||
13
gui/Dockerfile
Normal file
13
gui/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
FROM node:lts-alpine
|
||||
|
||||
WORKDIR /app
|
||||
RUN npm install -g @angular/cli http-server
|
||||
COPY rpk-gui/package*.json ./
|
||||
RUN npm install
|
||||
COPY rpk-gui/ .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 4200
|
||||
|
||||
CMD [ "npm", "run", "ng", "serve", "--", "--host", "0.0.0.0", "--disable-host-check" ]
|
||||
18
gui/rpk-gui/package-lock.json
generated
18
gui/rpk-gui/package-lock.json
generated
@@ -17,8 +17,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.21.0",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"@types/react": "^19.1.0",
|
||||
"@types/react-dom": "^19.1.1",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "^9.21.0",
|
||||
"eslint-plugin-react-hooks": "^5.1.0",
|
||||
@@ -2066,20 +2066,18 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.12.tgz",
|
||||
"integrity": "sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA==",
|
||||
"license": "MIT",
|
||||
"version": "19.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.0.tgz",
|
||||
"integrity": "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==",
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-dom": {
|
||||
"version": "19.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.4.tgz",
|
||||
"integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==",
|
||||
"version": "19.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.1.tgz",
|
||||
"integrity": "sha512-jFf/woGTVTjUJsl2O7hcopJ1r0upqoq/vIOoCj0yLh3RIXxWcljlpuZ+vEBRXsymD1jhfeJrlyTy/S1UW+4y1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.0.0"
|
||||
}
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
"better-auth": "^1.2.5",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-router": "^7.4.1",
|
||||
"react-router-auth"
|
||||
"react-router": "^7.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.21.0",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"@types/react": "^19.1.0",
|
||||
"@types/react-dom": "^19.1.1",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "^9.21.0",
|
||||
"eslint-plugin-react-hooks": "^5.1.0",
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
//https://www.robinwieruch.de/react-router-private-routes/
|
||||
|
||||
import { useState } from 'react'
|
||||
import reactLogo from './assets/react.svg'
|
||||
import viteLogo from '/vite.svg'
|
||||
import './App.css'
|
||||
|
||||
import {createBrowserRouter, Link, RouterProvider} from "react-router";
|
||||
import { EntityList } from "./page/entities/list.tsx";
|
||||
import {createBrowserRouter, Link, Route, RouterProvider, Routes} from "react-router";
|
||||
import { EntityList } from "./pages/entities/List.tsx";
|
||||
import {ProtectedRoute} from "./pages/auth/ProtectedRoute.tsx";
|
||||
|
||||
function App() {
|
||||
const [user, setUser] = useState<AuthUser | null>(null)
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
const router = createBrowserRouter([
|
||||
@@ -23,8 +27,13 @@ function App() {
|
||||
return (
|
||||
<>
|
||||
<RouterProvider router={router}>
|
||||
|
||||
</RouterProvider>
|
||||
<Routes>
|
||||
<Route index element={ <h1>INDEX</h1> } />
|
||||
<Route element={ <ProtectedRoute user={user} /> }>
|
||||
<Route path="toto" element={ <h1>PROTECTED ROUTE</h1>} />
|
||||
</Route>
|
||||
</Routes>
|
||||
<div>
|
||||
<a href="https://vite.dev" target="_blank">
|
||||
<img src={viteLogo} className="logo" alt="Vite logo" />
|
||||
|
||||
14
gui/rpk-gui/src/pages/auth/Login.tsx
Normal file
14
gui/rpk-gui/src/pages/auth/Login.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
export const Login = () => {
|
||||
async function handleLogin(e: any) {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={ handleLogin }>
|
||||
<input type={ "text" } name={ "email" } />
|
||||
<input type={ "password" } name={ "password" } />
|
||||
<input type={ "submit" } />
|
||||
</form>
|
||||
)
|
||||
}
|
||||
16
gui/rpk-gui/src/pages/auth/ProtectedRoute.tsx
Normal file
16
gui/rpk-gui/src/pages/auth/ProtectedRoute.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import {Navigate, Outlet} from "react-router";
|
||||
|
||||
type AuthUser = { id: string; name: string };
|
||||
|
||||
type ProtectedRouteProps = {
|
||||
user: AuthUser | null;
|
||||
redirectPath?: string;
|
||||
};
|
||||
|
||||
export const ProtectedRoute = ({ user, redirectPath = "/" }: ProtectedRouteProps) => {
|
||||
if (!user) {
|
||||
return <Navigate to={redirectPath} replace />;
|
||||
}
|
||||
|
||||
return <Outlet />;
|
||||
};
|
||||
15
gui/rpk-gui/src/pages/auth/Register.tsx
Normal file
15
gui/rpk-gui/src/pages/auth/Register.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
export const Register = () => {
|
||||
async function handleRegister(e: any) {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={ handleRegister }>
|
||||
<input type={ "text" } name={ "email" } />
|
||||
<input type={ "password" } name={ "password" }/>
|
||||
<input type={ "password" } name={ "confirm_password" }/>
|
||||
<input type={ "submit" } />
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
export const EntityList = (props: any) => {
|
||||
export const EntityList = () => {
|
||||
return (
|
||||
<h1>List des entity: Yoyoyo</h1>
|
||||
)
|
||||
Reference in New Issue
Block a user