Skip to content

Commit 7771fb4

Browse files
author
Max Nikitenko
committed
feat(auth): add sdk for JWT token generation and validation;
1 parent 379aa5a commit 7771fb4

File tree

2 files changed

+44
-10
lines changed

2 files changed

+44
-10
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Architecture part described in Margay Gateway core [repository](https://github.c
99
- Setup Subscriber or use example `examples/vanilla_worker.py` or `examples/vanilla_publisher.py`
1010
- Setup client or use example `examples/vanilla_client.py`
1111
- You can generate auth token by using [cli](https://github.com/moaddib666/wss-api-gateway.go/blob/main/cmd/indentety_provider/encoder.go)
12-
- Or just use your own identity provider
12+
- By using sdk auth
13+
- By using external indentety provider
1314
- Connect your backend
1415
- Basically that means:
1516
- You subscribe RMQ topic with your `CustomQueue` and listen for events
@@ -68,6 +69,18 @@ class EventPublisher(Publisher):
6869
self.publish_raw(event.serialize(), self.origin, recipient)
6970
```
7071

72+
## Auth
73+
### JWT
74+
```python
75+
from margay.sdk.auth import JWTAuth
76+
user = "John Snow"
77+
secret = "SuperSecret"
78+
identity_provider = JWTAuth(secret)
79+
token = identity_provider.issue_token(user)
80+
payload = identity_provider.verify_token(token, user)
81+
print(payload)
82+
```
83+
7184
## Debugging
7285
Set debug for SDKLogger
7386
```python

margay/sdk/auth/__init__.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,41 @@
66

77
class JWTAuth:
88
encoder = jwt.encode
9+
decoder = jwt.decode
10+
algorithm = "HS256"
11+
12+
class InvalidToken(Exception):
13+
pass
914

1015
def __init__(self, secret: str):
1116
self.secret = secret
1217

1318
def issue_token(self, client: str) -> str:
14-
return self.encoder(self.get_claims(client), self.secret, algorithm="HS256")
19+
return self.encoder(
20+
self.get_claims(client), self.secret, algorithm=self.algorithm
21+
)
22+
23+
def verify_token(self, token: str, client: str) -> dict:
24+
data = self.decoder(
25+
token,
26+
self.secret,
27+
algorithms=self.algorithm,
28+
audience=self._audience,
29+
issuer=self._issuer,
30+
)
31+
if data.get("jti") != client:
32+
raise self.InvalidToken(token)
33+
return data
1534

16-
@staticmethod
17-
def get_claims(client: str, ttl_hours=24) -> dict:
35+
def get_claims(self, client: str, ttl_hours=24) -> dict:
1836
return {
19-
"Audience": "localhost",
20-
"ExpiresAt": datetime.now(tz=timezone.utc) + timedelta(hours=ttl_hours),
21-
"Id": client,
22-
"IssuedAt": datetime.now(tz=timezone.utc),
23-
"Issuer": f"MargayPythonSDK-{socket.gethostname()}",
24-
"Subject": "client",
37+
"aud": self._audience,
38+
"exp": datetime.now(tz=timezone.utc) + timedelta(hours=ttl_hours),
39+
"jti": client,
40+
"iat": datetime.now(tz=timezone.utc),
41+
"iss": self._issuer,
42+
"sub": "client",
2543
}
44+
45+
_audience = "localhost"
46+
_issuer = f"MargayPythonSDK-{socket.gethostname()}"

0 commit comments

Comments
 (0)