Files
gapido-grpc-auth/README.md

79 lines
2.6 KiB
Markdown

# Gapido Backend Code Challenge
Python gRPC OTP authentication service with MongoDB, Redis, RabbitMQ, and selectable SMS providers.
## Architecture
- `auth-service`: async `grpc.aio` API for OTP login, token refresh, token revocation, and RBAC demo methods.
- `sms-worker`: RabbitMQ consumer that sends OTP messages through the configured SMS provider.
- MongoDB stores users and refresh-token sessions.
- Redis stores OTP hashes, TTL, verification attempts, and OTP request rate limits.
- RabbitMQ decouples authentication from SMS delivery.
## Run
```bash
cp .env.example .env
docker compose up --build
```
The gRPC service listens on `localhost:50051`. The demo UI is available at `http://localhost:8080`. RabbitMQ management is available at `http://localhost:15672` with `guest` / `guest`.
## SMS Provider
The SMS integration uses the Strategy pattern behind the `SmsClient` port. Select the provider with:
```env
SMS_PROVIDER=kavenegar
```
Supported values:
- `kavenegar`: uses `KAVENEGAR_API_KEY` and `KAVENEGAR_LOGIN_TEMPLATE`.
- `sms_ir`: uses `SMS_IR_API_KEY` and `SMS_IR_VERIFY_TEMPLATE_ID`.
- `debug`: local-only provider that stores the latest OTP in Redis for the demo UI.
## Demo UI
`demo-app` is a small FastAPI backend-for-frontend that calls `auth-service` over gRPC. It demonstrates how another microservice consumes the auth service.
Available browser actions:
- Request and verify OTP.
- Fetch the local debug OTP when `DEMO_ENABLE_DEBUG_OTP=true`.
- Call public, authenticated-user, and admin-only gRPC methods.
- Refresh and revoke tokens.
## Local Development
```bash
python -m venv .venv
pip install -e ".[dev]"
python -m gapido_auth.tools.generate_proto
pytest
```
## gRPC Methods
- `RequestOtp`: public; creates a short-lived OTP and publishes an SMS job.
- `VerifyOtp`: public; verifies OTP and returns access and refresh tokens.
- `RefreshToken`: public; rotates refresh token and returns a new token pair.
- `RevokeRefreshToken`: authenticated; revokes a refresh token session.
- `PublicPing`: public.
- `UserOnly`: requires any authenticated active user.
- `AdminOnly`: requires an authenticated admin.
Protected calls use metadata:
```text
authorization: Bearer <access_token>
```
## Security Notes
- OTP codes are generated with `secrets`, stored only as HMAC hashes in Redis, and expire after 120 seconds by default.
- OTP requests are rate-limited per mobile number and client identity.
- Refresh tokens are opaque random values; only SHA-256 hashes are persisted.
- Refresh tokens rotate on use.
- SMS providers are hidden behind adapters and mocked in tests.