Python Fastapi js аутентификация

Пишу код на Fastapi. маршрут авторизации

 @router.post("/login", response_model=TokenModel, summary="Authentication of a user in the app.",
            description="Uses user data to log in. Creates JWT token.")
async def login(response: Response, body: OAuth2PasswordRequestForm = Depends(), 
                db: Session = Depends(get_db)):
    user = await repository_users.get_user_by_email(body.username, db)
    if user is None:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid email")
    if not user.confirmed:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Email not confirmed")
    if not auth_services.verify_password(body.password, user.password):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid password")
    # Generate JWT
    access_token = await auth_services.create_access_token(data={"sub": user.email})
    refresh_token = await auth_services.create_refresh_token(data={"sub": user.email})
    await repository_users.update_token(user, refresh_token, db)
    return {"access_token": access_token, "refresh_token": refresh_token, "token_type": "bearer"}

 
    @router.get('/login')
async def login(request: Request):

    return templates.TemplateResponse(name='login.html', context={'request': request})

скрипт js

    document.getElementById("form").addEventListener("submit", function (event) {
    event.preventDefault();
    fetch("/api/auth/login", {
        method: "POST",
        body: new FormData(event.target),
        headers: {
            "Authorization": "Bearer YOUR_TOKEN"
        }
    })
        .then(response => {
            if (response.ok) {
                return response.json();
            } else {
                throw new Error('Failed to authenticate');
            }
        })
        .then(data => {
            window.location.href = '/api/page';
        })
        .catch(error => console.error("Error:", error));
});'''

Маршрут всех контактов если пользователь зарегистрирован.

@router.get("/",response_model = 
List[Seaman_is_personal_detailsResponse], 
summary = "List of all seamans.", description="No more 
than 10 requests per minute.")
async def read_seamans(skip: int = 0, limit: int = 100, 
                   current_user: Users = 
Depends(auth_services.get_current_user), 
                   db: Session = Depends(get_db)):
    users = await repository_seaman.get_seamans(skip, 
limit, current_user, db)
    return users

Маршрут html

@router.get('/')async def get_students_html(request: 
Request, seamans=Depends(read_seamans)
                        ):
returntemplates.TemplateResponse(name='list_seamans.html', 
context={'request': request, 'seamans': seamans})

В терминале аутентификация проходит успешно. Но когда перенаправляет на страницу пользователя выдает ошибку

INFO: 127.0.0.1:45752 - "GET /api/page/ HTTP/1.1" 401 Unauthorized

Понимаю что нужно передать токен на страницу пользователя. Но только как?


Ответы (1 шт):

Автор решения: Ivan Belyaev

Бэкенд возвращает вам пару токенов, их необходимо запомнить на стороне клиента (для начала попробуйте хранить access token в куки или local storage)

В тех местах, где предполагается доступ под авторизованным пользователем, вы должны передать бэкенду (например, из куки) access token в заголовке Authorization (как правило заголовок носит именно такое, а значение заголовка это строка вида

Bearer <your access token>

Есть множество источников о том как работать с токенами, попробуйте поискать материалы на тему json web tokens. После первичного погружения в тему рекомендую поинтересоваться временем жизни токенов и способами их безопасного хранения на клиенте (особенно касается refresh token)

→ Ссылка