I am trying to authenticate the user while running a code in python, but running into an error, "422 Unprocessable Entity". The code is running fine without the authentication, but I am unable to pass request.
from typing import Union
import requests
import uvicorn
from auth import authenticate
from fastapi import FastAPI
import boto3
import json
app = FastAPI()
client = boto3.client('eks')
boto3.set_stream_logger('')
@app.get("/test")
def test(request):
token = authenticate(request)
print("test")
if __name__ == "__main__":
print()
uvicorn.run(app, host="0.0.0.0", port=8000)
Code for authentication:
import jwt
from general.config import constants
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import APIException
from rest_framework.response import Response
jwtPrivateKey = constants.PRIVATE_KEY
def authenticate(request):
try:
auth_header_value = request.META.get("HTTP_AUTHORIZATION", "")
if auth_header_value:
if len(auth_header_value.split(" ", 1)) == 2:
authmeth, auth = request.META["HTTP_AUTHORIZATION"].split(
" ", 1)
if authmeth.lower() != "bearer" and authmeth.lower() != "basic":
raise TokenNotBearer()
token_value = jwt.decode(
jwt=auth, key=jwtPrivateKey, algorithms=['HS256', ])
return token_value
else:
raise TokenNotBearer()
else:
raise TokenNotProvided()
except (TokenExpiredOrInvalid, jwt.DecodeError):
raise TokenExpiredOrInvalid()
# when token is expired or invalid
class TokenExpiredOrInvalid(APIException):
...
# when token is not provided
class TokenNotProvided(APIException):
...
# when the token is not provided in the bearer
class TokenNotBearer(APIException):
...
How can I pass request in the api or how can I work with authentication passing request?
CodePudding user response:
@Ritika You are authenticating FastApi with django-restframework. reqeuste are not same on both app. Django get header from request instance, but Fastapi get header directly.
** Notice: function param authorization should match your header name! if your header Name is not Authorization, then fix it.
This may works,
# main.py
from typing import Union
import requests
import uvicorn
from auth import authenticate
# fix here
from fastapi import FastAPI, Header
import boto3
import json
app = FastAPI()
client = boto3.client('eks')
boto3.set_stream_logger('')
# fix here
@app.get("/test")
def test(authorization:str = Header(default=None)):
token = authenticate(authorization)
print("test")
if __name__ == "__main__":
print()
uvicorn.run(app, host="0.0.0.0", port=8000)
# auth.py
import jwt
from general.config import constants
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import APIException
from rest_framework.response import Response
jwtPrivateKey = constants.PRIVATE_KEY
def authenticate(auth_header_value):
try:
if auth_header_value is not None:
if len(auth_header_value.split(" ", 1)) == 2:
authmeth, auth = auth_header_value.split(
" ", 1)
if authmeth.lower() != "bearer" and authmeth.lower() != "basic":
raise TokenNotBearer()
token_value = jwt.decode(
jwt=auth, key=jwtPrivateKey, algorithms=['HS256', ])
return token_value
else:
raise TokenNotBearer()
else:
raise TokenNotProvided()
except (TokenExpiredOrInvalid, jwt.DecodeError):
raise TokenExpiredOrInvalid()
# when token is expired or invalid
class TokenExpiredOrInvalid(APIException):
...
# when token is not provided
class TokenNotProvided(APIException):
...
# when the token is not provided in the bearer
class TokenNotBearer(APIException):
...
CodePudding user response:
You need to mention Request on type annotation explicitly.
UPDATE: This is not related to type annotation. See another answer.
Try this,
from typing import Union
import requests
import uvicorn
from auth import authenticate
# fix here
from fastapi import FastAPI, Request
import boto3
import json
app = FastAPI()
client = boto3.client('eks')
boto3.set_stream_logger('')
# fix here
@app.get("/test")
def test(request: Request):
token = authenticate(request)
print("test")
if __name__ == "__main__":
print()
uvicorn.run(app, host="0.0.0.0", port=8000)