REST-сервис с помощью FastApi
Не могу понять, что именно мешает авторизоваться. Окно авторизации вылезает, но вне зависимости от правильности введенных данных, выдает ошибку "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}
Ответы (2 шт):
Автор решения: Умар Камбулатов
→ Ссылка
def verify_password(username, password):
if username in users:
if pwd_context.verify(password, users[username]["password"]):
return True
return False
return False
Автор решения: yuwisasha
→ Ссылка
Вы пытаетесь использовать 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)):