how to connect krakend config file for jwt token generation in fastapi

322 views
Skip to first unread message

Karthik

unread,
Sep 5, 2023, 3:06:24 AM9/5/23
to KrakenD Community
JWT generation works when I call  API directly at http://localhost:8000/token?username=user&password=password but does not work when I call it through the KrakenD Gateway at http://localhost:8080/token?username=user&password=password......401 or 500 error 


This the issue im facing  how to sort it out.ill share my config file and api.py file for generating token also set symmetric.json ,please give me a support to solve the issue ....


symmetric.json

{
"kty": "oct",
"kid": "sim2",
"use": "sig",
"k": "ydjenjkxnmsdfkejnsc"
}


api.py
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
import jwt
from datetime import datetime, timedelta
from typing import Optional
import json
from fastapi import FastAPI, Depends, HTTPException
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# Secret key for JWT
SECRET_KEY = "ydjenjkxnmsdfkejnsc"
# Token expiration time (change as needed)
ACCESS_TOKEN_EXPIRE_MINUTES = 30


fake_users_db = {
"user": {
"username": "user",
"password": "password"
}
}

# User model
class User(BaseModel):
username: str

# Token model
class Token(BaseModel):
access_token: str
token_type: str


app = FastAPI()

# Configure CORS
origins = [
]


app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)


# Function to read JWK private key from file
def read_jwk_private_key():
with open("symmetric.json", "r") as key_file:
return json.load(key_file)["k"] # Get the 'k' field from the JWK

# JWT token generation function
def create_access_token(data: dict, expires_delta: 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})

# Load the symmetric key from the JWK file
jwk_private_key = read_jwk_private_key()

# Sign the JWT using the symmetric key
encoded_jwt = jwt.encode(to_encode, jwk_private_key, algorithm="HS256")
return encoded_jwt


# Endpoint to generate a JWT token
@app.post("/token", response_model=Token)
async def generate_access_token(username: str, password: str):
user = fake_users_db.get(username)
if user is None or password != user["password"]:
raise HTTPException(status_code=401, detail="Incorrect username or password")

access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(data={"sub": username}, expires_delta=access_token_expires)
# Generate a refresh token
refresh_token_expires = timedelta(days=7) # Change as needed
refresh_token = create_access_token(data={"sub": username}, expires_delta=refresh_token_expires)
return {"access_token": access_token, "token_type": "bearer", "refresh_token": refresh_token}

# ms2.py (Backend Service 2 on port 8001)


@app.get("/service2")
def index():
return {"message": "Hello from Backend Service 2!"}

@app.get("/")
def index():
return {"message": "Hello from Backend Service 2!"}



if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
krekendconfig.json
{
"version": 3,
"endpoints": [
{
"endpoint": "/token",
"method": "POST",
"output_encoding": "json",
"extra_config": {
"allow_origins": ["http://localhost:8000"],
"jwk_url":" https://./symmetric.json",
"alg":"HS256",
"token_type": "bearer",
"expose_headers": ["Authorization"],
"cache": true,
"max_age": "12h",
"allow_methods": ["GET", "POST"],
"allow_headers": ["Authorization", "Content-Type"],
"allow_credentials": true
}
},
"backend": [
{
"url_pattern": "/",
}
]
},
{
"endpoint": "/service2",
"method": "GET",
"output_encoding": "json",
"backend": [
{
"url_pattern": "/",
"host": [
]
}
]
}
]
}

Albert Lombarte

unread,
Sep 5, 2023, 4:20:21 AM9/5/23
to KrakenD Community, karthi...@gmail.com
Hi,

I have only looked at the configuration file and KrakenD, and I don't know how you got it, but it's completely invented. This is not a KrakenD configuration at all, and it looks as if it were generated by ChatGPT :)
Please refer to the documentation to write configuration files and check their validity. For instance:

  1. The URL $schema you are using does not exist. Where did you take this from?
  2. You are using version: 3 which is for KrakenD v2.0 and above, but then you include namespaces of KrakenD v1.3 and below (github.com/devopsfaith/krakend-cors)
  3. The CORS module does not do JWT validation, you need to use the auth/validation component instead. You will need two modules, one for CORS, and another for JWT.
  4. The jwk_url points to an unreachable file https://./symmetric.json (and it was named jwk-url in older KrakenDs
Bottom line, make sure what KrakenD version you use, and then stick to its configuration syntax. KrakenD can't do magic and interpret a configuration it does not recognize. You can check if a file is valid using the linter: https://www.krakend.io/docs/configuration/check/

Best regards

El dia dimarts, 5 de setembre de 2023 a les 9:06:24 UTC+2, karthi...@gmail.com va escriure:

Karthik

unread,
Sep 5, 2023, 6:00:52 AM9/5/23
to KrakenD Community, Albert Lombarte, karthi...@gmail.com
can you please say how to connect my jwt backend to krakend gateway  and how jwk  works

Daniel Lopez

unread,
Sep 5, 2023, 8:50:43 AM9/5/23
to KrakenD Community, karthi...@gmail.com, Albert Lombarte

Notice that you will also need to define a set of input_query_strings (https://www.krakend.io/docs/endpoints/#input_query_strings)

Cheers!

ponmarimuthu s

unread,
Sep 20, 2023, 3:43:29 PM9/20/23
to KrakenD Community, Daniel Lopez, karthi...@gmail.com, Albert Lombarte
Yes, Just add this in your endpoint declaration,
 "input_headers": [
        "Authorization",
        "Accept",
        "Content-Type"  #if it is a POST endpoint
      ]

Reply all
Reply to author
Forward
0 new messages