Package: ellar-jwt
IntroductionJWT utilities module for Ellar.Installation$(venv)pipinstallellar-jwtUsageImportJWTModule:fromellar.commonimportModulefromellar_jwtimportJWTModule@Module(modules=[JWTModule.setup(signing_secret_key='my_private_key')])classAuthModule:passInjectJWTServicewhere its needed as shown belowfromellar_jwtimportJWTServicefromellar.diimportinjectable@injectable()classAuthService:def__init__(self,jwt_service:JWTService)->None:self.jwt_service=jwt_serviceasyncdefsign_in(self,username:str,password:str)->t.Dict:user=awaitself.user_service.find_one(username)ifuser.password!=credentials.password:raiseHTTPException(status_code=status.HTTP_403_FORBIDDEN)return{'access_token':awaitself.jwt_service.sign_async(user.dict())}JWTModule SetupThere are two ways in config JWTModulesetup:JWTModule.setuptakes some parameters that allows instant configuration of theJWTConfigurationschema required by theJWTServiceFor example:fromellar.commonimportModulefromellar_jwtimportJWTModule@Module(modules=[JWTModule.setup(signing_secret_key='my_private_key',issuer='https://google.com')])classAuthModule:passregister:JWTModule.registerallow you to provide JWT configuration in Ellar application config object usingJWT_CONFIGkey.
The register function will create aModuleSetupobject that will inject applicationconfigto a JWT config factoryfor example:# config.pyimportjsonfromdatetimeimporttimedeltaclassDevelopmentConfig:JWT_CONFIG={'algorithm':"HS256",# allow_algorithms=["HS256","HS384","HS512","RS256","RS384","RS512","ES256","ES384","ES512"]'leeway':0,# t.Union[float, int, timedelta]'signing_secret_key':'secret',# secret or private key'verifying_secret_key':"",# public key'audience':None,'issuer':None,'jwk_url':None,'jti':"jti",'lifetime':timedelta(minutes=5),# token lifetime, this will example in 5 mins'json_encoder':json.JSONEncoder# token lifetime, this will example}Inauth/module.pyfromellar.commonimportModulefromellar_jwtimportJWTModule@Module(modules=[JWTModule.register_setup()])classAuthModule:passJWT Configuration OptionsimportjsonfromdatetimeimporttimedeltaJWT_CONFIG={'algorithm':"HS256",# allow_algorithms=["HS256","HS384","HS512","RS256","RS384","RS512","ES256","ES384","ES512"]'leeway':0,# t.Union[float, int, timedelta]'signing_secret_key':'secret',# secret or private key'verifying_secret_key':"",# public key'audience':None,'issuer':None,'jwk_url':None,'jti':"jti",'lifetime':timedelta(minutes=5),# token lifetime, this will example in 5 mins'json_encoder':json.JSONEncoder# token lifetime, this will example}lifetimeAdatetime.timedeltaobject is employed to define the validity duration of the tokens.
When generating a token, thistimedeltavalue is combined with the presentUTCtime to establish the defaultexpclaim value for the token.algorithmThe chosen algorithm from thePyJWTlibrary governs the signing and verification procedures for tokens.
For symmetric HMAC signing and verification, you have the option to use the following algorithms:HS256,HS384, andHS512.
In the case of an HMAC algorithm, the signing_secret_key serves both as the signing and verifying key, rendering theverifying_secret_keysetting redundant.
On the other hand, for asymmetric RSA signing and verification, you can opt for the following algorithms:RS256,RS384, andRS512.
In this scenario, selecting an RSA algorithm mandates configuring thesigning_secret_keysetting with an RSA private key string. Correspondingly, theverifying_secret_keysetting must contain an RSA public key stringsigning_secret_keyThe signing key utilized for signing the content of generated tokens has distinct requirements based on the signing protocol.
For HMAC signing, it should be a randomly generated string containing at least as many bits as dictated by the signing protocol.
Conversely, for RSA signing, it should be a string encompassing an RSA private key with a length of 2048 bits or more.
As Simple JWT defaults to 256-bit HMAC signing, thesigning_secret_keysetting automatically takes on the value of your django project'sSECRET_KEY.
While this default is practical, it's advisable for developers to modify this setting to a value separate from the django project's secret key.
This adjustment facilitates easier token signing key changes if the key is ever compromised.verifying_secret_keyThe verification key is employed to authenticate the contents of generated tokens.
In case an HMAC algorithm is indicated by thealgorithmsetting, theverifying_secret_keyconfiguration is disregarded, and thesigning_secret_keysetting value will be utilized.
However, if an RSA algorithm is designated by thealgorithmsetting, theverifying_secret_keyparameter must be populated with an RSA public key stringaudienceThe audience claim is incorporated into generated tokens and/or verified within decoded tokens.
If configured asNone, this element is omitted from tokens and isn't subjected to validation.issuerThe issuer claim is added to generated tokens and/or validated within decoded tokens.
If configured asNone, this attribute is omitted from tokens and isn't subjected to validation.jwk_urlThe JWK_URL serves the purpose of dynamically retrieving the required public keys for token signature verification.
For instance, with Auth0, you could configure it as 'https://yourdomain.auth0.com/.well-known/jwks.json'.
If set toNone, this field is omitted from the token backend and remains inactive during validation.leewayLeeway provides a buffer for the expiration time, which can be defined as an integer representing seconds or a datetime.timedelta object.
For further details, please consult the following link:https://pyjwt.readthedocs.io/en/latest/usage.html#expiration-time-claim-expjtiThe claim designated for storing a token's unique identifier, which is utilized to distinguish revoked tokens within the blacklist application.
There might be instances where an alternative claim other than the default "jti" claim needs to be employed for storing this valuejson_encoderJSON Encoder class that will be used by thePYJWTto encode thejwt_payload.API SpecTheJwtServiceusesPYJWTunderneath.jwt_service.sign(payload: dict, headers: Dict[str, t.Any] = None, **jwt_config: t.Any) -> strCreates a jwt token for the provided payload. Also, you can override default jwt config by using passing some keyword argument as ajwt_configjwt_service.sign_async(payload: dict, headers: Dict[str, t.Any] = None, **jwt_config: t.Any) -> strAsync action forjwt_service.signjwt_service.decode(token: str, verify: bool = True, **jwt_config: t.Any) -> t.Dict[str, t.Any]:Verifies and decodes provided token. And raises JWTException exception if token is invalid or expiredjwt_service.decode_async(token: str, verify: bool = True, **jwt_config: t.Any) -> t.Dict[str, t.Any]:Async action forjwt_service.decodeLicenseEllar isMIT licensed.