0% found this document useful (0 votes)
5 views10 pages

Building Generative AI Services With FastAPI51

The document outlines the implementation of a JWT authentication system using FastAPI, detailing user registration, login, logout, and password reset functionalities. It emphasizes the importance of security measures such as email verification, token revocation, and the potential for implementing two-factor authentication. Additionally, it suggests using third-party authentication providers to enhance security features.

Uploaded by

xiaowang198808
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views10 pages

Building Generative AI Services With FastAPI51

The document outlines the implementation of a JWT authentication system using FastAPI, detailing user registration, login, logout, and password reset functionalities. It emphasizes the importance of security measures such as email verification, token revocation, and the potential for implementing two-factor authentication. Additionally, it suggests using third-party authentication providers to enhance security features.

Uploaded by

xiaowang198808
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

if not await self.password_service.

verify
form_data.password, user.hashed_passw
):
raise UnauthorizedException
return await self.token_service.create_ac

async def get_current_user(self, credentials


if [Link] != "Bearer":
raise UnauthorizedException
if not (token := [Link]
raise UnauthorizedException
payload = self.token_service.decode(token
if not await self.token_service.validate
raise UnauthorizedException
if not (username := [Link]("username
raise UnauthorizedException
if not (user := await self.user_service.g
raise UnauthorizedException
return user

async def logout(self, credentials: AuthHeade


payload = self.token_service.decode(crede
await self.token_service.deactivate(paylo

# Add Password Reset Method


async def reset_password(self): ...
The core authentication logic of the application that
verifies whether a user exists and their password
credentials. Returns False if any checks fail.

You can now use the AuthService to register and


authenticate users using their credentials. Refer to Example 8-
11 to see how the AuthService is used to create the required
dependencies for a dedicated authentication router.

Example 8-11. Implement authentication controllers to


enable login and registration functionality

# routes/[Link]

from typing import Annotated


from entities import User
from fastapi import APIRouter, Depends
from models import TokenOut, UserOut
from [Link] import AuthService

auth_service = AuthService()
RegisterUserDep = Annotated[User, Depends(auth_se
AuthenticateUserCredDep = Annotated[
str, Depends(auth_service.authenticate_user_w
]
AuthenticateUserTokenDep = Annotated[User, Depend
PasswordResetDep = Annotated[None, Depends(auth_s
router = APIRouter(prefix="/auth", tags=["Authent

@[Link]("/register")
async def register_user_controller(new_user: Regi
return new_user

@[Link]("/token")
async def login_for_access_token_controller(
access_token: AuthenticateUserCredDep,
) -> TokenOut:
return {"access_token": access_token, "token_

@[Link]("/logout", dependencies=[Depends(aut
async def logout_access_token_controller() -> dic
return {"message": "Logged out"}

@[Link]("reset-password")
async def reset_password_controller(credentials:
return {
"message": "If an account exists, "
"a password reset link will be sent to th
}

Create an instance of the AuthService and declare


reusable annotated dependencies.

Create a separate API router for authentication endpoints.


Implement endpoints for registering users, user login
(token issuance), user logout (token revocation), and
password reset.

Since the LogoutUserDep dependency won’t return


anything, inject it within the dependency array of the
router.

Once you have a dedicated authentication router, create a


separate resource router to group all your resource endpoints
within. With both routers, you can now add them to your
FastAPI app, as shown in Example 8-12, to complete the JWT
authentication work.

Example 8-12. Refactor FastAPI application to use routers

# routes/[Link]

from fastapi import APIRouter

router = APIRouter(prefix="/generate", tags=["Res

@[Link]("/generate/text", ...)
def serve_language_model_controller(...):
...

@[Link]("/generate/audio", ...)
def serve_text_to_audio_model_controller(...)
...

... # Add other controllers to the resource route

# [Link]

from typing import Annotated


import routes
from entities import User
from fastapi import Depends, FastAPI
from [Link] import AuthService

auth_service = AuthService()
AuthenticateUserDep = Annotated[User, Depends(aut

...

app = FastAPI(lifespan=lifespan)

app.include_router([Link], prefix="/a
app.include_router(
[Link],
dependencies=[AuthenticateUserDep],
prefix="/generate",
tags=["Generate"],
)
... # Add other routes to the app here

Refactor existing endpoints to be grouped under a


separate API router named the resource router.

Add both auth and resource routers to the FastAPI app


router.

Protect the resource endpoints by injecting the


AuthenticateUserDep dependency at the router level.
Requests must now include an Authorization header
with a bearer token to be authenticated with the resource
router.

Massive congratulations! You now have a fully working GenAI


service protected by JWT authentication, which can be
deployed to production with some additional work.

In the next section, you’ll learn a few ideas on additional


enhancements you can make to the system to tighten the
security of your JWT authentication system.
Authentication flows

You will need to handle several authentication flows to fully


implement a usable JWT authentication system.

The core authentication flows include the following:

User registration

New users will want to register a new account by


providing their emails and a secure password. Your
authentication logic may check for password strength, no
existing users with the same email, and that the user
reconfirms the password and email. You should also avoid
storing the user’s raw password in the database.

User login

On each user login, your system can generate, store, and


provide a unique temporary access token (i.e., JWT) if a
user supplies their correct credentials. Your protected
resource server routers should reject any incoming
requests that don’t contain a valid JWT. Valid JWTs can be
verified through their signature and checked against the
valid tokens specified in the database.

User logout
When the user logs out, your system can revoke the
currently issued token and prevent future malicious login
attempts with the current token.

In addition to the core flows, you should also consider


secondary flows to implement a production-ready
authentication system. These flows could be used for:

Verifying identity

To prevent spambots from registering active accounts in


your system and consuming server resources, you will
want some form of user verification mechanism in place.
For instance, add email verification by integrating an
emailing server to your authentication system.

Resetting passwords

Users can forget their passwords at any time. You will


want to implement a flow for users to reset their
passwords. If a user resets their password, all active
tokens in the database against their user account must be
revoked.

Forcing logout

Revoke all previously generated access tokens of a user on


all clients to prevent stolen tokens from being used to
access the system.
Disabling user accounts

Administrators or users may want to disable their


accounts to prevent future login attempts.

Deleting user accounts

This is required if users would like to remove their


accounts from your systems. Depending on your data
storage requirements, you may want to delete personally
identifiable information while keeping other associated
data.

Blocking successive login attempts

Temporarily disable an account that has had multiple


failed login attempts within a short time span.

Providing refresh tokens

Generate both short-lived access tokens and long-lived


refresh tokens. Since access tokens can expire frequently
to reduce the window of opportunity for attackers to use a
stolen token, clients can reuse their refresh token to
request new access tokens. This removes the need for
frequent logins while maintaining security of the system
against attackers.
Two-factor authentication (2FA) or multifactor authentication
(MFA)

You can secure your system against exposed password-


protected accounts by requiring 2FA or MFA as an
additional protection layer. 2FA/MFA examples include
SMS/email verification, one-time passwords (OTPs), or
randomly generated number sequences from a paired
authentication app as a second login step before an access
token can be generated.

WARNING

The aforementioned list is not exhaustive. You may want to check out “OWASP Top 10
Web Applications Security Risks” and “OWASP Authentication Cheat Sheet” for the
full list of considerations when implementing your own JWT authentication from
scratch.

In addition to following the OWASP top 10 guidelines, you should use security
mechanisms such as rate limiting, geo/IP-tracking, and account lockouts to defend
against various attacks.

You can also consider using third-party authentication providers (such as


Okta/Auth0, Firebase Auth, KeyCloak, Amazon Cognito, etc.) that include these
security features in their services.

While credentials-based authentication using JWTs can be


considered a production-ready authentication system and be

You might also like