paint-brush
Ndlela yo Tirhisa Sisiteme ya Vuhlayiseki bya Switirhisiwa swo Tala hi FastAPI, Redis, na JWThi@emperorsixpacks
Matimu lamantshwa

Ndlela yo Tirhisa Sisiteme ya Vuhlayiseki bya Switirhisiwa swo Tala hi FastAPI, Redis, na JWT

hi Andrew David 10m2024/10/09
Read on Terminal Reader

Ku leha ngopfu; Ku hlaya

Eka dyondzo leyi, hi ta tirhisa JWT (JSON Web Tokens) ku pfumelela swikombelo. Tanihi leswi xitirhisiwa xa hina xi nga riki na xiyimo (leswi vulaka leswaku a xi na memori ya swikombelo swa khale), hi lava ndlela yo rhumela seshini na data ya mutirhisi. JWT yi kahle swinene eka ku lawula vuhlayiseki eka switirhisiwa leswi nga riki na xiyimo naswona yi endla ntirho wa kahle swinene.
featured image - Ndlela yo Tirhisa Sisiteme ya Vuhlayiseki bya Switirhisiwa swo Tala hi FastAPI, Redis, na JWT
Andrew David  HackerNoon profile picture
0-item
1-item



Tikhampani to tala letikulu ta thekinoloji ti nyikela xivumbeko xo kufumela lexi pfumelelaka vatirhisi ku nghena eka switirhisiwa swo tala. Vatirhisi va nga lawula switirhisiwa swa vona, va vona leswaku hi swihi leswi nghenisiweke, hambi ku ri ku huma eka xitirhisiwa xihi na xihi hi ku tirhisa switirhisiwa swihi na swihi swa vona leswi ngheneke. Namuntlha, ndzi lava ku lavisisa ndlela leyi ndzi nga tirhisaka sisiteme ya vuhlayiseki leyi fanaka hi ku tirhisa Redis na JWT.

Kutani leswi swi tirha njhani kahle-kahle?

Eka leswi, ndzi endle xiboho xo tirhisa;

  • Fast-API ya le ndzhaku

  • Redis ya ku hlayisa


Hi ta tirhisa JWT (JSON Web Tokens) ku pfumelela swikombelo. Tanihi leswi xitirhisiwa xa hina xi nga riki na xiyimo (leswi vulaka leswaku a xi na memori ya swikombelo swa khale), hi lava ndlela yo rhumela seshini na data ya mutirhisi. JWT yi kahle swinene eka ku lawula vuhlayiseki eka switirhisiwa leswi nga riki na xiyimo, naswona yi endla ntirho wa kahle swinene.


Kambe, xin’wana lexi nga riki xinene xa JWT hileswaku loko u nghenisa payload yo tala eka token, yi leha. Eka sisiteme ya hina, ndzi endle xiboho xo katsa ntsena session_id na username eka token. Rungula leri ri ringanerile ku pfumelela swikombelo handle ko endla leswaku xikombiso xi va xikulu ku tlula mpimo.e yi ta tirhisa JWT (JSON Web Tokens) ku pfumelela swikombelo. Tanihi leswi xitirhisiwa xa hina xi nga riki na xiyimo (leswi vulaka leswaku a xi na memori ya swikombelo swa khale), hi lava ndlela yo rhumela seshini na data ya mutirhisi. JWT yi kahle swinene eka ku lawula vuhlayiseki eka switirhisiwa leswi nga riki na mfumo, naswona yi endla ntirho wa kahle swinene eka mhaka leyi.

U te session_id? kambe hi tirhisa JWT na app ya hina eka stateless

Eka xiyimo lexi, "session" swi vula xitirhisiwa kumbe ndlela leyi mutirhisi a tirhisanaka na app ya hina ha yona. Kahle-kahle, i xitirhisiwa lexi mutirhisi a ngheneke eka xona. Nkarhi wun’wana na wun’wana loko mutirhisi a endla xikombelo xo nghena, hi tumbuluxa seshini leyintshwa (xitirhisiwa) eka sisiteme ya hina leyi nga na vuxokoxoko hinkwabyo bya xitirhisiwa lebyi faneleke. Data leyi yi ta hlayisiwa eka Redis ku endlela swikombelo swa nkarhi lowu taka.

Alright, ahi kumeni ku coding 😁

Nchumu wo sungula ku wu endla i ku tiyisisa leswaku u na Redis leyi nghenisiweke eka muchini wa wena wa laha kaya. Ku nghenisa Redis, kongoma eka https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/ naswona landzelela swiletelo leswi kongomeke eka sisiteme ya wena yo tirha.


Endzhaku ka sweswo, hi nghenisa python. Hikwalaho ka leswi, ndzi ta va ndzi tirhisa python 3.11 (a ndzi si vona xilaveko xo ndlandlamuxa ku ya eka 3.12 ku fikela sweswi, ku vula ntiyiso xivangelo xin’we ntsena lexi endlaka leswaku ndzi tirhisa hambi ku ri 3.11 i hikwalaho ka StrEnum, handle ka sweswo ndza ha yi tsakela 3.10)


Endzhaku ka sweswo, hi fanele ku nghenisa vutlhokovetseri, leyi i package manager leyi ndzi yi tirhisaka

 pip install poetry # or python3.11 -m install poetry


Sweswo swi lulamisiwile, kutani yana emahlweni u clone repo

 git clone https://github.com/emperorsixpacks/multi_device_sign_in_with_redis.git && cd server poetry shell && poetry install # create a new virtual environment and install all dependanceies

Ku veka vuhlanganisi bya hina bya Redis

 import os from redis import Redis load_dotenv(".env") REDIS_HOST = os.getenv("REDIS_HOST", "localhost") REDIS_PORT = os.getenv("REDIS_PORT", "6379") redis_client = Redis(REDIS_HOST, int(REDIS_PORT))

Ku lulamisiwa ka database

Ndzi endlile database ya demo eka demo_users.json leyi nga yona leyi hi nga ta va hi yi tirhisa eka dyondzo leyi.

 { "user124": { "username": "user124", "email": "[email protected]", "password": "1234", "bio": "This is my brief bio" }, "user123": { "username": "user123", "email": "[email protected]", "password": "1234", "bio": "This is my brief bio" } }

Sweswi, hi fanele ku engetela swikimi swa hina na mintirho ya mupfuni eka database ya hina. Ku komisa, a ndzi nge veki khodi hinkwayo laha.

 @dataclass class Session: """ A class to represent a user's session. Attributes: session_id (str): A unique id for the session. device_name (str): The name of the device used for the session. ip_address (str): The ip address of the device used for the session. device_id (str): A unique id for the device. date_created (datetime): The date and time the session was created. """ session_id: str = field(default_factory=create_new_session_id) device_name: str = field(default=None) ip_address: str = field(default=None) device_id: str = field(default_factory=generate_new_device_id) date_created: datetime = field(default_factory=now_date_time_to_str) @dataclass class User: """ A class to represent a user. Attributes: username (str): The username of the user. email (str): The email of the user. password (str): The password of the user. bio (str): The bio of the user. sessions (List[Session] | None): A list of Session objects representing the user's sessions. """ username: str = field(default=None) email: str = field(default=None) password: str = field(default=None) bio: str = field(default=None) sessions: List[Session] | None = None @property def __dict__(self): """ Returns a dictionary representing the user. Returns: Dict[str, Any]: A dictionary representing the user """ return { "username": self.username, "email": self.email, "password": self.password, "bio": self.bio, "sessions": self.return_session_dict(), } def return_session_dict(self): """ Returns a list of dictionaries representing the user's sessions. If the sessions field is a list of Session objects, returns a list of dictionaries where each dictionary is the __dict__ of a Session object. If the sessions field is a list of dictionaries, returns the list as is. Returns: List[Dict[str, Any]]: A list of dictionaries representing the user's sessions """ try: return [session.__dict__ for session in self.sessions] except AttributeError: return [session for session in self.sessions] # Utiliy finctions def return_user_from_db(username) -> User | None: """ Retrieves a user from the database by their username. Args: username (str): The username of the user to be retrieved Returns: User | None: The user if found, None otherwise """ with open("demo_users.json", "r", encoding="utf-8") as file: user = json.load(file).get(str(username), None) return User(**user) or None

Ku lulamisiwa ka sevha

Hi tirhisa FastAPI ku fambisa app ya hina, kutani a hi fambeni hi ya veka sweswo eka

 # Setting up server from fastapi import FastAPI from fastapi.responses import JSONResponse app = FastAPI( name="Multi device sign in with Redis", description="Multi device sign in with Redis in stateless applications", ) @app.get("/") def index_route(): return JSONResponse(content={"Message": "hello, this seems to be working :)"}) if __name__ == "__main__": import uvicorn uvicorn.run("server:app", host="0.0.0.0", port=8000, reload=True, use_colors=True)


Alright leswi swi kahle application ya hina yi vonaka yi hlangana kahle

Ku nghena / ku nghena

Nkarhi wun’wana na wun’wana loko mutirhisi a nghena eka sisiteme, hi lava ndlela yo tumbuluxa session_id na ku hlayisa session yoleyo eka Redis, kun’we na ti session ta vona tin’wana hinkwato.


Loko mutirhisi a nghena, hi ta rhanga hi tiyisisa xikombelo ku tiyisisa leswaku xa tirha. Loko se yi tiyisisiwile, hi nga kuma vuxokoxoko hinkwabyo bya xitirhisiwa eka xikombelo. Endzhaku ka sweswo, hi ta hlayisa vuxokoxoko lebyi eka Redis, hi tumbuluxa xikombiso lexintshwa, ivi hi tlherisela xikombiso xexo eka mutirhisi.

 @app.post("/login") def login_route( form: Annotated[LoginForm, Depends()], request: Request ) -> JSONResponse: """ Handles a login request. Args: form (Annotated[LoginForm, Depends()]): The form data containing the username and password request (Request): The request containing the User-Agent header and client host Returns: JSONResponse: A JSON response containing a JWT token if the login is successful, otherwise a JSONResponse with a 404 status code and a message indicating that the username or password is invalid """ username = form.username password = form.password # Authenticate the user user = authenticate_user(username, password) if user is None: return JSONResponse( status_code=404, content={"message": "Invalid username or password"} ) # Create a new session session = Session( device_name=request.headers.get("User-Agent"), ip_address=request.client.host ) # Get the user from the cache user_from_cache = get_user_from_cache(username) if user_from_cache is None: return JSONResponse(content={"message": "one minute"}, status_code=404) # Get the user's sessions user_sessions = get_sessions(userid=username) # Add the new session to the user's sessions try: user_sessions.append(session) except AttributeError: user_sessions = [session] # Update the user in the cache user_from_cache.sessions = user_sessions update_user_cache(userid=username, new_data=user_from_cache) # Create a JWT token token = create_token(Token(user=username, session_id=session.session_id)) # Return the JWT token return JSONResponse(content={"message": "logged in", "token": token})

Ku huma/ ku huma

Lexi i xiphemu xo olova. Nkarhi wun’wana na wun’wana loko mutirhisi a endla xikombelo eka app ya hina, hi decode token ya Bearer ku vuyisa session_id na username . Hi nga ha vutisa Redis hi ku tirhisa username .


Loko hi kuma ku fambelana, hi susa session leyi fambelanaka na session_id eka token leyi decoded. Hi xikombiso, loko seshini yi nga ri kona, hi tlherisela ntsena rungula eka mutirhisi. Leswi swi kombisa leswaku mutirhisi se u humile eka xitirhisiwa xexo ku suka eka xitirhisiwa xo hambana, kumbe leswaku xikombiso a xi tirhi.

 @app.post("/logout") def logout_route(request: Request): """ Handles a request to log out the user. This endpoint will delete the user's session from the cache and return a JSON response with a message indicating that the user has been logged out. Args: request (Request): The request containing the Authorization header with the JWT token Returns: JSONResponse: A JSON response containing the message "logged out" if the token is valid, otherwise a JSONResponse with a 404 status code and a message indicating that the token is invalid """ # Get the JWT token from the Authorization header _, token = get_authorization_scheme_param(request.headers.get("Authorization")) # Decode the JWT token payload = decode_token(token) # Check if the token is invalid if payload is None: return JSONResponse(content={"message": "Invalid token"}, status_code=404) # Check if the user or session does not exist if get_single_session(userid=payload.user, session_id=payload.session_id) is None or get_user_from_cache( userid=payload.user) is None: return JSONResponse(content={"message": "Invalid token"}, status_code=404) # Delete the session from the cache delete_session(payload.user, payload.session_id) # Return a JSON response with a message indicating that the user has been logged out return JSONResponse(content={"message": "logged out"})


So yeah, sweswo a swi nga tika ngopfu, a swi tano ke? Ndzi vile na phurojeke leyi enhlokweni ya mina ku ringana mavhiki ma nga ri mangani sweswi, naswona a ndzi lava ku yi ringeta. Hambi leswi fambiselo leri ri nga hetisekangiki hi ku helela (ndzi vula leswaku, ku hava fambiselo leri nga riki na swihoxo swa rona) swi le rivaleni leswaku hi nga endla leri ri antswa. Xikombiso, xana hi swi lawula njhani swikombelo leswi humaka eka ndhawu yo fana na Curl kumbe console app kumbe hambi ku ri postman? Swikombelo swo tala ku suka eka swihlovo leswi swi nga endla leswaku ku va na tisexini to tala, hikwalaho ku tata db ya hina hi data leyi nga lavekiki. Ina, hi nga kambela ku vona laha xikombelo xi humaka kona ivi hi tumbuluxa logic ya hina ku khoma sweswo, kambe ku vula ntiyiso, sweswo swi ta va ntirho wo tala. Hi yona mhaka leyi ndzi nga bumabumeriki ku aka tisisiteme ta mpfumelelo na ku tiyisisa eka ti-app ta vuhumelerisi, handle ka loko u ri “agba” wa xiviri (munjhiniyara lonkulu). Ndzi nga tsakela ku tirhisa OAuth 2.0 (Google kumbe Apple) kumbe muphakeri wa le handle wo fana na Kinde kumbe Auth0 . Naswona loko u tshovekile ku fana na mina naswona u tirhisa EdgeDB , yi ta na auth system leyi lunghekeleke ku yi tirhisa ehandle ka bokisi. Hi ndlela leyi, loko ku humelela swo karhi, u na un'wana wo sola ku nga ri intern ntsena 🙂.

L O A D I N G
. . . comments & more!

About Author

Andrew David  HackerNoon profile picture
Andrew David @emperorsixpacks
I watch cartoons, if I was Eren I would have done the same thing. I love computers.

HANG TAGS

XITLHOKOVETSELO LEXI XI NYIKERIWE EKA...