REST-сервис с помощью FastApi

Рейтинг: 0Ответов: 2Опубликовано: 14.06.2023

Не могу понять, что именно мешает авторизоваться. Окно авторизации вылезает, но вне зависимости от правильности введенных данных, выдает ошибку "POST /token HTTP/1.1" 401 Unauthorized Вроде токен выделяется.... Подскажите, кто увидел ошибку.

from fastapi import FastAPI, HTTPException, Depends
from datetime import datetime, timedelta
from jose import jwt
from passlib.context import CryptContext
from fastapi.security import HTTPBasicCredentials

app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
secret_key = "your-secret-key"
access_token_expire_minutes = 30


users = {
    "admin": {
        "username": "admin",
        "password": pwd_context.hash("admin123"),
        "salary": 5000,
        "last_promotion": "2023-01-01"
    },
    "user1": {
        "username": "user1",
        "password": pwd_context.hash("user123"),
        "salary": 3000,
        "last_promotion": "2022-06-01"
    }
}

def verify_password(username, password):
    if username in users and pwd_context.verify(password, users[username]["password"]):
        return True
    return False

def create_access_token(username):
    expires = datetime.utcnow() + timedelta(minutes=access_token_expire_minutes)
    payload = {"username": username, "expires": expires}
    return jwt.encode(payload, secret_key, algorithm="HS256")

@app.post("/token")
def login(username: str, password: str):
    if not verify_password(username, password):
        raise HTTPException(status_code=401, detail="Invalid username or password")
    
    access_token = create_access_token(username)
    return {"access_token": access_token, "token_type": "bearer"}

def get_current_salary(username):
    return users[username]["salary"]

def get_next_promotion(username):
    last_promotion = datetime.strptime(users[username]["last_promotion"], "%Y-%m-%d")
    next_promotion = last_promotion + timedelta(days=365)
    return next_promotion.strftime("%Y-%m-%d")

def authenticate(credentials: HTTPBasicCredentials = Depends()):
    if not verify_password(credentials.username, credentials.password):
        raise HTTPException(status_code=401, detail="Invalid username or password")
    
    return credentials.username

@app.get("/salary")
def get_salary(username: str = Depends(authenticate)):
    salary = get_current_salary(username)
    next_promotion = get_next_promotion(username)
    return {"salary": salary, "next_promotion": next_promotion}

Ответы

▲ 0
def verify_password(username, password):
    if username in users:
       if pwd_context.verify(password, users[username]["password"]):
          return True
       return False
    return False
▲ 0

Вы пытаетесь использовать HTTP-Basic-auth

def authenticate(credentials: HTTPBasicCredentials = Depends()):
    if not verify_password(credentials.username, credentials.password):
        raise HTTPException(status_code=401, detail="Invalid username or password")
    
    return credentials.username

вместе с OAuth2 scopes.

def create_access_token(username):
    expires = datetime.utcnow() + timedelta(minutes=access_token_expire_minutes)
    payload = {"username": username, "expires": expires}
    return jwt.encode(payload, secret_key, algorithm="HS256")

Скорее всего ошибка кроется в этом, советую выбрать что-то одно. Также согласно документации вам стоит добавить

from fastapi.security import HTTPBasic

и исправить.

def authenticate(credentials: HTTPBasicCredentials = Depends(security)):