I have a React application that talks to a Django API and it uses a JWT token to authenticate requests. I wanna use Clerk to authenticate users on the frontend but I don't know how I'll get the JWT token to authenticate the requests to the backend API, can anyone help?
The following is what the front-end code would look like:
import { useAuth } from "@clerk/clerk-react"
function App() {
const { getToken } = useAuth();
const sendRequest = async (e) => {
e.preventDefault()
fetch(
api_url,
{
method: 'GET',
headers: { Authorization: `Bearer ${await getToken()}` },
},
)
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.error(error));
}
...
}
The following is an example of authentication on the back-end (using FastAPI).
import requests
import jwt
from jwt.algorithms import RSAAlgorithm
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
@app.get("/")
async def root(request: Request):
auth_header = request.headers.get("Authorization")
try:
user_id = validate_token(auth_header)
except AuthenticationException as e:
raise HTTPException(status_code=400, detail=str(e))
print(f"{user_id = }")
return {"user": user_id}
def validate_token(auth_header: str) -> str:
"""
returns user_id if valid
raises AuthenticationException otherwise
"""
try:
token = auth_header.split(" ")[1]
except (AttributeError, KeyError):
raise AuthenticationException("No authentication token provided")
jwks = requests.get(
"https://api.clerk.com/v1/jwks",
headers={
"Accept": "application/json",
"Authorization": f"Bearer {CLERK_SECRET_KEY}",
},
).json()
public_key = RSAAlgorithm.from_jwk(jwks["keys"][0])
try:
payload = jwt.decode(
token,
public_key,
algorithms=["RS256"],
options={"verify_signature": True},
)
except jwt.ExpiredSignatureError:
raise AuthenticationException("Token has expired.")
except jwt.DecodeError:
raise AuthenticationException("Token decode error.")
except jwt.InvalidTokenError:
raise AuthenticationException("Invalid token.")
user_id = payload.get("sub")
return user_id
Make sure you replace CLERK_SECRET_KEY
with your secret key.