| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- """Authentication decorator for protecting API endpoints."""
- from functools import wraps
- from flask import request
- import jwt
- from app.services.auth_service import AuthService
- def require_auth(f):
- """Decorator to require JWT authentication for an endpoint.
-
- Validates the Authorization header contains a valid JWT token.
- Sets request.current_admin with the decoded token payload if valid.
-
- Returns:
- 401 Unauthorized if token is missing, expired, or invalid
- """
- @wraps(f)
- def decorated(*args, **kwargs):
- auth_header = request.headers.get('Authorization', '')
-
- # Check for Bearer token
- if not auth_header:
- return {
- 'success': False,
- 'error': 'Authentication required',
- 'code': 'UNAUTHORIZED'
- }, 401
-
- # Extract token from "Bearer <token>" format
- parts = auth_header.split()
- if len(parts) != 2 or parts[0].lower() != 'bearer':
- return {
- 'success': False,
- 'error': 'Invalid authorization header format',
- 'code': 'INVALID_TOKEN'
- }, 401
-
- token = parts[1]
-
- try:
- payload = AuthService.verify_token(token)
- request.current_admin = payload
- except jwt.ExpiredSignatureError:
- return {
- 'success': False,
- 'error': 'Token expired',
- 'code': 'TOKEN_EXPIRED'
- }, 401
- except jwt.InvalidTokenError:
- return {
- 'success': False,
- 'error': 'Invalid token',
- 'code': 'INVALID_TOKEN'
- }, 401
-
- return f(*args, **kwargs)
- return decorated
|