Authentication Flow¶
The Evrmore Authentication system implements a secure, wallet-based authentication flow that leverages the cryptographic capabilities of the Evrmore blockchain. This page explains the authentication process in detail.
Overview¶
| 1. Challenge Generation | The server generates a unique challenge for the user's Evrmore address |
| 2. Signature Creation | The user signs the challenge with their Evrmore wallet |
| 3. Verification | The server verifies the signature against the challenge |
| 4. Token Issuance | Upon successful verification, a JWT token is issued |
| 5. Authentication | The token is used for subsequent API requests |
Step 1: Challenge Generation¶
When a user attempts to authenticate, the server generates a unique challenge for their Evrmore address.
# Server-side code
from evrmore_authentication import EvrmoreAuth
auth = EvrmoreAuth()
challenge = auth.generate_challenge("EXaMPLeEvRMoReAddResS")
What happens behind the scenes:
- The system creates a unique challenge text, typically a random string with a timestamp
- The challenge is stored in the database with:
- The user's Evrmore address
- Creation timestamp
- Expiration timestamp (default: 15 minutes)
- A
user_challengesrecord is created to track challenge ownership - Event hooks (if defined) are triggered for challenge generation
API Endpoint:
The response includes the challenge text:
{
"challenge": "Sign this message to authenticate: a8f7e9d1c2b3a4f5e6d7c8b9a1f2e3d4",
"expires_at": "2023-03-14T15:30:45Z"
}
Step 2: Signature Creation¶
The user signs the challenge with their Evrmore wallet. This is typically done client-side using wallet software or an extension.
Example using evrmore-cli:
evrmore-cli signmessage "EXaMPLeEvRMoReAddResS" "Sign this message to authenticate: a8f7e9d1c2b3a4f5e6d7c8b9a1f2e3d4"
The output is a base64-encoded signature:
Step 3: Verification¶
The server verifies the signature against the challenge and the Evrmore address.
# Server-side code
session = auth.authenticate(
evrmore_address="EXaMPLeEvRMoReAddResS",
challenge=challenge,
signature="H9LJFkR+a0MFm1jSvmoBZ1wQobuSGPQ2C1TW/m9FVwnQJNjyZLX3ZzOOHI01jEL59YtJFXBH9PnwH..."
)
What happens behind the scenes:
- The system retrieves the challenge from the database and ensures it:
- Exists
- Belongs to the specified Evrmore address
- Hasn't expired
- Hasn't been used before
- The signature is verified cryptographically against the challenge and address
- The challenge is marked as used to prevent replay attacks
- Event hooks (if defined) are triggered for successful authentication
- If a user doesn't exist in the database, they are created automatically
API Endpoint:
POST /authenticate
{
"evrmore_address": "EXaMPLeEvRMoReAddResS",
"challenge": "Sign this message to authenticate: a8f7e9d1c2b3a4f5e6d7c8b9a1f2e3d4",
"signature": "H9LJFkR+a0MFm1jSvmoBZ1wQobuSGPQ2C1TW/m9FVwnQJNjyZLX3ZzOOHI01jEL59YtJFXBH9PnwH..."
}
Step 4: Token Issuance¶
Upon successful verification, a JWT (JSON Web Token) is generated and issued to the user.
What happens behind the scenes:
- A new session is created in the database with:
- User ID
- JWT token
- Creation timestamp
- Expiration timestamp (default: 30 minutes)
- The JWT is signed using the configured secret key and algorithm
- The token contains claims including:
- User ID
- Evrmore address
- Expiration time
- Issuance time
API Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiZXZybW9yZV9hZGRyZXNzIjoiRVhhTVBMZUV2Uk1vUmVBZGRSZXNTIiwiZXhwIjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"expires_at": "2023-03-14T16:00:45Z",
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"evrmore_address": "EXaMPLeEvRMoReAddResS"
}
}
Step 5: Authentication¶
The JWT token is used for subsequent API requests to authenticate the user.
# Client-side code for making authenticated requests
import requests
headers = {
"Authorization": f"Bearer {token}"
}
response = requests.get("https://api.example.com/protected-resource", headers=headers)
What happens behind the scenes:
- The server extracts the token from the Authorization header
- The token is verified to ensure:
- It's properly signed
- It hasn't expired
- It hasn't been revoked
- The user information is extracted from the token
- The request proceeds with the authenticated user context
API Endpoint for Token Validation:
Response:
{
"valid": true,
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"evrmore_address": "EXaMPLeEvRMoReAddResS"
}
}
Logout Process¶
To invalidate a token (logout):
What happens behind the scenes:
- The session associated with the token is marked as inactive
- The token can no longer be used for authentication
- Event hooks (if defined) are triggered for logout
API Endpoint:
Security Considerations¶
The Evrmore Authentication flow offers several security benefits:
-
No Password Storage: The system never stores user passwords, eliminating password database theft risks.
-
Challenge-Response Mechanism: Each authentication requires a new challenge, preventing replay attacks.
-
Cryptographic Verification: Uses blockchain-grade cryptography to verify signatures.
-
Short-lived Challenges: Challenges expire quickly (default: 15 minutes) to limit attack windows.
-
Single-Use Challenges: Each challenge can only be used once, preventing replay attacks.
-
JWT Best Practices: Implements security best practices for JWT handling.
-
Database Integrity: Challenges and sessions are tracked in the database to prevent misuse.
For additional security, consider implementing:
- Rate limiting for challenge generation
- IP-based restrictions
- Additional user verification methods
- Hardware wallet support