Last active
May 26, 2025 13:38
-
-
Save ShaikhZayan/ffb16b87baef36519b12c9856768fca1 to your computer and use it in GitHub Desktop.
Revisions
-
ShaikhZayan revised this gist
Jul 25, 2024 . No changes.There are no files selected for viewing
-
ShaikhZayan revised this gist
Jul 25, 2024 . No changes.There are no files selected for viewing
-
ShaikhZayan revised this gist
Jul 25, 2024 . 1 changed file with 43 additions and 36 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,6 +3,7 @@ You can use FastAPI with OAuth2 for authentication and integrate it with a Next. ### 1. Set Up FastAPI with OAuth2 First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a basic example: #### FastAPI OAuth2 Setup 1. **Install the necessary dependencies:** @@ -18,7 +19,7 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba from jose import JWTError, jwt from passlib.context import CryptContext from datetime import datetime, timedelta from typing import Optional, Dict app = FastAPI() @@ -34,7 +35,7 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") # In-memory user storage for demonstration purposes fake_users_db: Dict[str, Dict[str, str]] = { "user@example.com": { "username": "user", "full_name": "User Example", @@ -44,23 +45,22 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba } } def verify_password(plain_password: str, hashed_password: str) -> bool: return pwd_context.verify(plain_password, hashed_password) def get_user(db: Dict[str, Dict[str, str]], email: str) -> Optional[Dict[str, str]]: if email in db: return db[email] def authenticate_user(fake_db: Dict[str, Dict[str, str]], email: str, password: str) -> Optional[Dict[str, str]]: user = get_user(fake_db, email) if not user: return None if not verify_password(password, user['hashed_password']): return None return user def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str: to_encode = data.copy() if expires_delta: expire = datetime.utcnow() + expires_delta @@ -85,7 +85,7 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba ) return {"access_token": access_token, "token_type": "bearer"} async def get_current_user(token: str = Depends(oauth2_scheme)) -> Optional[Dict[str, str]]: credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", @@ -104,7 +104,7 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba return user @app.get("/users/me") async def read_users_me(current_user: Dict[str, str] = Depends(get_current_user)): return current_user ``` @@ -119,21 +119,25 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba 2. **Create an authentication provider in Next.js using `next-auth`:** ```typescript // pages/api/auth/[...nextauth].ts import NextAuth from 'next-auth'; import CredentialsProvider from 'next-auth/providers/credentials'; import axios from 'axios'; export default NextAuth({ providers: [ CredentialsProvider({ name: 'Credentials', credentials: { email: { label: 'Email', type: 'text' }, password: { label: 'Password', type: 'password' }, }, authorize: async (credentials) => { try { const res = await axios.post('http://localhost:8000/token', { username: credentials?.email, password: credentials?.password, }); if (res.status === 200) { @@ -149,13 +153,13 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba }), ], callbacks: { async jwt({ token, user }) { if (user) { token.accessToken = user.token; } return token; }, async session({ session, token }) { session.accessToken = token.accessToken; return session; }, @@ -168,24 +172,24 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba 3. **Create a sign-in page:** ```typescript // pages/auth/signin.tsx import { useState } from 'react'; import { signIn } from 'next-auth/react'; export default function SignIn() { const [email, setEmail] = useState<string>(''); const [password, setPassword] = useState<string>(''); const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const result = await signIn('credentials', { redirect: false, email, password, }); if (result?.error) { // handle error console.error(result.error); } else { @@ -216,12 +220,12 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba 4. **Use the authentication token in your API calls:** ```typescript import axios from 'axios'; import { useSession } from 'next-auth/react'; const fetchData = async () => { const { data: session } = useSession(); if (session) { const res = await axios.get('http://localhost:8000/users/me', { headers: { @@ -236,17 +240,19 @@ First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a ba ``` ### 3. Secure Next.js Routes You can secure your Next.js routes by checking if the user is authenticated using the `getSession` method from `next-auth/react`. ```typescript // pages/protected.tsx import { GetServerSideProps } from 'next'; import { getSession } from 'next-auth/react'; export default function ProtectedPage() { return <div>Protected content</div>; } export const getServerSideProps: GetServerSideProps = async (context) => { const session = await getSession(context); if (!session) { @@ -261,10 +267,11 @@ export async function getServerSideProps(context) { return { props: { session }, }; }; ``` ### Summary - **FastAPI** handles authentication, issuing JWT tokens for authenticated users. - **Next.js** uses `next-auth` to manage authentication on the client side, obtaining tokens from FastAPI. - API calls from the frontend include the JWT token in the authorization header to access protected endpoints in FastAPI. -
ShaikhZayan renamed this gist
Jul 25, 2024 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
ShaikhZayan revised this gist
Jul 25, 2024 . No changes.There are no files selected for viewing
-
ShaikhZayan renamed this gist
Jul 25, 2024 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
ShaikhZayan revised this gist
Jul 25, 2024 . No changes.There are no files selected for viewing
-
ShaikhZayan revised this gist
Jul 25, 2024 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -269,4 +269,6 @@ export async function getServerSideProps(context) { - **Next.js** uses `next-auth` to manage authentication on the client side, obtaining tokens from FastAPI. - API calls from the frontend include the JWT token in the authorization header to access protected endpoints in FastAPI. By following this setup, you can have a secure and functional login system with FastAPI as the backend and Next.js as the frontend. Make Sure To Star The Repo If You Think It's Useful TY! -
ShaikhZayan renamed this gist
Jul 25, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ You can use FastAPI with OAuth2 for authentication and integrate it with a Next.js frontend to create a login system. You can manage your backend logic and authentication in FastAPI and handle the frontend logic, including authorization, in Next.js. Here's a high-level overview of how you can achieve this: ### 1. Set Up FastAPI with OAuth2 First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a basic example: -
ShaikhZayan revised this gist
Jul 25, 2024 . 1 changed file with 259 additions and 338 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,351 +1,272 @@ Yes, you can use FastAPI with OAuth2 for authentication and integrate it with a Next.js frontend to create a login system. You can manage your backend logic and authentication in FastAPI and handle the frontend logic, including authorization, in Next.js. Here's a high-level overview of how you can achieve this: ### 1. Set Up FastAPI with OAuth2 First, you'll need to set up FastAPI with OAuth2 for authentication. Here's a basic example: #### FastAPI OAuth2 Setup 1. **Install the necessary dependencies:** ```bash pip install fastapi uvicorn python-jose passlib ``` 2. **Create the FastAPI app:** ```python from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jose import JWTError, jwt from passlib.context import CryptContext from datetime import datetime, timedelta from typing import Optional app = FastAPI() # Secret key to encode and decode JWT tokens SECRET_KEY = "your_secret_key" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 # Password hashing context pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") # OAuth2 scheme oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") # In-memory user storage for demonstration purposes fake_users_db = { "user@example.com": { "username": "user", "full_name": "User Example", "email": "user@example.com", "hashed_password": pwd_context.hash("password"), "disabled": False, } } def verify_password(plain_password, hashed_password): return pwd_context.verify(plain_password, hashed_password) def get_user(db, email: str): if email in db: user_dict = db[email] return user_dict def authenticate_user(fake_db, email: str, password: str): user = get_user(fake_db, email) if not user: return False if not verify_password(password, user['hashed_password']): return False return user def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): to_encode = data.copy() if expires_delta: expire = datetime.utcnow() + expires_delta else: expire = datetime.utcnow() + timedelta(minutes=15) to_encode.update({"exp": expire}) encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt @app.post("/token") async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()): user = authenticate_user(fake_users_db, form_data.username, form_data.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password", headers={"WWW-Authenticate": "Bearer"}, ) access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( data={"sub": user['email']}, expires_delta=access_token_expires ) return {"access_token": access_token, "token_type": "bearer"} async def get_current_user(token: str = Depends(oauth2_scheme)): credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) email: str = payload.get("sub") if email is None: raise credentials_exception except JWTError: raise credentials_exception user = get_user(fake_users_db, email=email) if user is None: raise credentials_exception return user @app.get("/users/me") async def read_users_me(current_user: dict = Depends(get_current_user)): return current_user ``` ### 2. Integrate with Next.js #### Next.js Authentication 1. **Install the necessary dependencies:** ```bash npm install next-auth axios ``` 2. **Create an authentication provider in Next.js using `next-auth`:** ```javascript // pages/api/auth/[...nextauth].js import NextAuth from 'next-auth'; import Providers from 'next-auth/providers'; import axios from 'axios'; export default NextAuth({ providers: [ Providers.Credentials({ name: 'Credentials', authorize: async (credentials) => { try { const res = await axios.post('http://localhost:8000/token', { username: credentials.email, password: credentials.password, }); if (res.status === 200) { return { token: res.data.access_token }; } else { return null; } } catch (error) { console.error(error); return null; } }, }), ], callbacks: { async jwt(token, user) { if (user) { token.accessToken = user.token; } return token; }, async session(session, token) { session.accessToken = token.accessToken; return session; }, }, pages: { signIn: '/auth/signin', }, }); ``` 3. **Create a sign-in page:** ```javascript // pages/auth/signin.js import { useState } from 'react'; import { signIn } from 'next-auth/client'; export default function SignIn() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleSubmit = async (e) => { e.preventDefault(); const result = await signIn('credentials', { redirect: false, email, password, }); if (result.error) { // handle error console.error(result.error); } else { // redirect to home page window.location.href = '/'; } }; return ( <form onSubmit={handleSubmit}> <input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="submit">Sign In</button> </form> ); } ``` 4. **Use the authentication token in your API calls:** ```javascript import axios from 'axios'; import { useSession } from 'next-auth/client'; const fetchData = async () => { const [session] = useSession(); if (session) { const res = await axios.get('http://localhost:8000/users/me', { headers: { Authorization: `Bearer ${session.accessToken}`, }, }); console.log(res.data); } }; fetchData(); ``` ### 3. Secure Next.js Routes You can secure your Next.js routes by checking if the user is authenticated using the `getSession` method from `next-auth/client`. ```javascript // pages/protected.js import { getSession } from 'next-auth/client'; export default function ProtectedPage() { return <div>Protected content</div>; } export async function getServerSideProps(context) { const session = await getSession(context); if (!session) { return { redirect: { destination: '/auth/signin', permanent: false, }, }; } return { props: { session }, }; } ``` ### Summary - **FastAPI** handles authentication, issuing JWT tokens for authenticated users. - **Next.js** uses `next-auth` to manage authentication on the client side, obtaining tokens from FastAPI. - API calls from the frontend include the JWT token in the authorization header to access protected endpoints in FastAPI. By following this setup, you can have a secure and functional login system with FastAPI as the backend and Next.js as the frontend. -
ShaikhZayan revised this gist
Jul 25, 2024 . 2 changed files with 351 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,351 @@ Here's a formatted guide for adding a cookie-based authentication system to a Next.js application while integrating with FastAPI. You can include this in your GitHub README: --- ## Cookie-Based Authentication System with Next.js and FastAPI Adding a cookie-based authentication system to Next.js while integrating with FastAPI involves setting up both the backend and frontend to handle user signup, login, and authentication using cookies. ### 1. FastAPI Setup #### FastAPI OAuth2 Setup with Signup First, add signup functionality to your FastAPI app and configure OAuth2 to handle cookies. **Install dependencies:** ```bash pip install fastapi uvicorn python-jose passlib ``` **FastAPI app with signup and OAuth2:** ```python from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jose import JWTError, jwt from passlib.context import CryptContext from datetime import datetime, timedelta from typing import Optional from pydantic import BaseModel app = FastAPI() SECRET_KEY = "your_secret_key" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") # In-memory user storage for demonstration purposes fake_users_db = {} class User(BaseModel): username: str email: str full_name: Optional[str] = None disabled: Optional[bool] = None class UserInDB(User): hashed_password: str def verify_password(plain_password, hashed_password): return pwd_context.verify(plain_password, hashed_password) def get_user(db, email: str): if email in db: user_dict = db[email] return UserInDB(**user_dict) def authenticate_user(fake_db, email: str, password: str): user = get_user(fake_db, email) if not user: return False if not verify_password(password, user.hashed_password): return False return user def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): to_encode = data.copy() if expires_delta: expire = datetime.utcnow() + expires_delta else: expire = datetime.utcnow() + timedelta(minutes=15) to_encode.update({"exp": expire}) encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt @app.post("/token") async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()): user = authenticate_user(fake_users_db, form_data.username, form_data.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password", headers={"WWW-Authenticate": "Bearer"}, ) access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( data={"sub": user.email}, expires_delta=access_token_expires ) return {"access_token": access_token, "token_type": "bearer"} @app.post("/signup") async def signup(email: str, password: str, full_name: Optional[str] = None): if email in fake_users_db: raise HTTPException(status_code=400, detail="Email already registered") hashed_password = pwd_context.hash(password) fake_users_db[email] = { "username": email, "email": email, "full_name": full_name, "hashed_password": hashed_password, "disabled": False, } return {"message": "User created"} async def get_current_user(token: str = Depends(oauth2_scheme)): credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) email: str = payload.get("sub") if email is None: raise credentials_exception except JWTError: raise credentials_exception user = get_user(fake_users_db, email=email) if user is None: raise credentials_exception return user @app.get("/users/me") async def read_users_me(current_user: User = Depends(get_current_user)): return current_user ``` ### 2. Next.js Setup #### Dependencies **Install the necessary packages:** ```bash npm install next-auth axios cookie ``` **Create a `next-auth` configuration file:** ```javascript // pages/api/auth/[...nextauth].js import NextAuth from 'next-auth'; import CredentialsProvider from 'next-auth/providers/credentials'; import axios from 'axios'; export default NextAuth({ providers: [ CredentialsProvider({ name: 'Credentials', credentials: { email: { label: 'Email', type: 'text' }, password: { label: 'Password', type: 'password' }, }, authorize: async (credentials) => { try { const res = await axios.post('http://localhost:8000/token', { username: credentials.email, password: credentials.password, }); if (res.status === 200) { return { accessToken: res.data.access_token }; } else { return null; } } catch (error) { console.error(error); return null; } }, }), ], callbacks: { async jwt({ token, user }) { if (user) { token.accessToken = user.accessToken; } return token; }, async session({ session, token }) { session.accessToken = token.accessToken; return session; }, }, pages: { signIn: '/auth/signin', signUp: '/auth/signup', }, }); ``` **Create a signup page:** ```javascript // pages/auth/signup.js import { useState } from 'react'; import axios from 'axios'; export default function Signup() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [fullName, setFullName] = useState(''); const handleSubmit = async (e) => { e.preventDefault(); try { await axios.post('http://localhost:8000/signup', { email, password, full_name: fullName }); alert('Signup successful'); } catch (error) { console.error(error); alert('Signup failed'); } }; return ( <form onSubmit={handleSubmit}> <input type="text" placeholder="Full Name" value={fullName} onChange={(e) => setFullName(e.target.value)} /> <input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="submit">Sign Up</button> </form> ); } ``` **Create a sign-in page:** ```javascript // pages/auth/signin.js import { useState } from 'react'; import { signIn } from 'next-auth/react'; export default function SignIn() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleSubmit = async (e) => { e.preventDefault(); const result = await signIn('credentials', { redirect: false, email, password, }); if (result.error) { alert(result.error); } else { window.location.href = '/'; } }; return ( <form onSubmit={handleSubmit}> <input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="submit">Sign In</button> </form> ); } ``` **Handle authentication with cookies in API calls:** ```javascript // utils/axios.js import axios from 'axios'; import { getSession } from 'next-auth/react'; export const fetchWithAuth = async (url, options = {}) => { const session = await getSession(); const headers = session ? { Authorization: `Bearer ${session.accessToken}` } : {}; return axios(url, { ...options, headers: { ...headers, ...options.headers }, }); }; ``` **Use the `fetchWithAuth` utility to make authenticated API calls:** ```javascript // pages/protected.js import { useEffect, useState } from 'react'; import { fetchWithAuth } from '../utils/axios'; export default function ProtectedPage() { const [data, setData] = useState(null); useEffect(() => { const fetchData = async () => { try { const response = await fetchWithAuth('http://localhost:8000/users/me'); setData(response.data); } catch (error) { console.error(error); } }; fetchData(); }, []); return ( <div> <h1>Protected Content</h1> {data ? <pre>{JSON.stringify(data, null, 2)}</ pre> : <p>Loading...</p>} </div> ); } ``` ### Summary - **FastAPI**: Manages signup and login, issuing JWT tokens. - **Next.js**: Utilizes `next-auth` for authentication and cookies, with dedicated signup and login pages. - **Cookies**: Stored and sent with each request, enabling authenticated API calls to FastAPI endpoints. Feel free to customize further according to your needs! --- You can copy this directly into your README file, and it should provide clear instructions for setting up cookie-based authentication between Next.js and FastAPI. -
ShaikhZayan revised this gist
Jul 25, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1 +1 @@ #Hello -
ShaikhZayan created this gist
Jul 25, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ # Hello