|
| 1 | +# Flexible Authentication for OpenSensor API |
| 2 | + |
| 3 | +This document describes the new flexible authentication system that allows users to access historical data endpoints using either Fief tokens (existing method) or device API keys (new method). |
| 4 | + |
| 5 | +## Problem Solved |
| 6 | + |
| 7 | +Previously, users authenticated in the web app had no way to get temporary tokens for direct API access outside the web interface. They could only: |
| 8 | +- Use Fief access tokens directly (not ideal for external tools) |
| 9 | +- Generate device-specific API keys (permanent, only for data submission) |
| 10 | + |
| 11 | +## Solution |
| 12 | + |
| 13 | +The new flexible authentication system allows users to use their existing device API keys to access historical data endpoints directly, providing a simple solution for data export without complex token management. |
| 14 | + |
| 15 | +## Features |
| 16 | + |
| 17 | +### ✅ Device API Key Authentication |
| 18 | +- Use existing device API keys for historical data retrieval |
| 19 | +- No need to manage separate temporary tokens |
| 20 | +- Automatic device access validation |
| 21 | + |
| 22 | +### ✅ Fief Token Caching |
| 23 | +- Reduced load on Fief authentication server |
| 24 | +- 10-minute cache TTL for token validation |
| 25 | +- Automatic cache invalidation on errors |
| 26 | + |
| 27 | +### ✅ Backward Compatibility |
| 28 | +- All existing Fief token authentication continues to work |
| 29 | +- No breaking changes to current API usage |
| 30 | + |
| 31 | +### ✅ Security |
| 32 | +- API keys can only access their associated device data |
| 33 | +- Strict device ID and name matching |
| 34 | +- Same security model as existing system |
| 35 | + |
| 36 | +## Usage Examples |
| 37 | + |
| 38 | +### 1. Using Device API Key (New Method) |
| 39 | + |
| 40 | +```bash |
| 41 | +# Get temperature data using device API key |
| 42 | +curl -H "X-API-Key: your_device_api_key_here" \ |
| 43 | + "https://api.opensensor.io/temp/device123|MyDevice?page=1&size=10" |
| 44 | +``` |
| 45 | + |
| 46 | +```python |
| 47 | +import requests |
| 48 | + |
| 49 | +headers = {"X-API-Key": "your_device_api_key_here"} |
| 50 | +response = requests.get( |
| 51 | + "https://api.opensensor.io/temp/device123|MyDevice", |
| 52 | + headers=headers |
| 53 | +) |
| 54 | +data = response.json() |
| 55 | +``` |
| 56 | + |
| 57 | +```javascript |
| 58 | +const response = await fetch('https://api.opensensor.io/temp/device123|MyDevice', { |
| 59 | + headers: { |
| 60 | + 'X-API-Key': 'your_device_api_key_here' |
| 61 | + } |
| 62 | +}); |
| 63 | +const data = await response.json(); |
| 64 | +``` |
| 65 | + |
| 66 | +### 2. Using Fief Token (Existing Method) |
| 67 | + |
| 68 | +```bash |
| 69 | +# Get temperature data using Fief token |
| 70 | +curl -H "Authorization: Bearer your_fief_token_here" \ |
| 71 | + "https://api.opensensor.io/temp/device123|MyDevice?page=1&size=10" |
| 72 | +``` |
| 73 | + |
| 74 | +## Supported Endpoints |
| 75 | + |
| 76 | +All historical data endpoints now support both authentication methods: |
| 77 | + |
| 78 | +- `/temp/{device_id}` - Temperature data |
| 79 | +- `/humidity/{device_id}` - Humidity data |
| 80 | +- `/CO2/{device_id}` - CO2 data |
| 81 | +- `/moisture/{device_id}` - Moisture sensor data |
| 82 | +- `/pH/{device_id}` - pH data |
| 83 | +- `/VPD/{device_id}` - Vapor Pressure Deficit data |
| 84 | +- `/pressure/{device_id}` - Pressure data |
| 85 | +- `/lux/{device_id}` - Light intensity data |
| 86 | +- `/liquid/{device_id}` - Liquid level data |
| 87 | +- `/relays/{device_id}` - Relay status data |
| 88 | +- `/pumps/{device_id}` - Pump data |
| 89 | + |
| 90 | +## Authentication Flow |
| 91 | + |
| 92 | +### Device API Key Flow |
| 93 | +1. User provides API key in `X-API-Key` header |
| 94 | +2. System validates API key exists in database |
| 95 | +3. System checks if API key is authorized for requested device |
| 96 | +4. If authorized, data is returned |
| 97 | + |
| 98 | +### Fief Token Flow (with caching) |
| 99 | +1. User provides token in `Authorization: Bearer` header |
| 100 | +2. System checks Redis cache for token validation |
| 101 | +3. If cache miss, validates with Fief server and caches result |
| 102 | +4. If valid, checks device access permissions |
| 103 | +5. If authorized, data is returned |
| 104 | + |
| 105 | +## Error Responses |
| 106 | + |
| 107 | +### 401 Unauthorized |
| 108 | +```json |
| 109 | +{ |
| 110 | + "detail": "Authentication required" |
| 111 | +} |
| 112 | +``` |
| 113 | +- No authentication provided (neither API key nor token) |
| 114 | + |
| 115 | +### 403 Forbidden |
| 116 | +```json |
| 117 | +{ |
| 118 | + "detail": "API key is not authorized to access device device123|MyDevice" |
| 119 | +} |
| 120 | +``` |
| 121 | +- API key doesn't match the requested device |
| 122 | + |
| 123 | +```json |
| 124 | +{ |
| 125 | + "detail": "Invalid API key" |
| 126 | +} |
| 127 | +``` |
| 128 | +- API key not found in database |
| 129 | + |
| 130 | +## Getting Your API Key |
| 131 | + |
| 132 | +1. Log into the web interface at https://opensensor.io |
| 133 | +2. Navigate to the sensor dashboard |
| 134 | +3. Your existing device API keys are displayed with masked values |
| 135 | +4. Use the full API key value for direct API access |
| 136 | + |
| 137 | +## Implementation Details |
| 138 | + |
| 139 | +### Files Modified |
| 140 | + |
| 141 | +1. **`opensensor/users.py`** |
| 142 | + - Added flexible authentication functions |
| 143 | + - Added Fief token caching |
| 144 | + - Added device access validation for API keys |
| 145 | + |
| 146 | +2. **`opensensor/collection_apis.py`** |
| 147 | + - Updated historical data routes to use flexible authentication |
| 148 | + - Improved error messages for different auth types |
| 149 | + |
| 150 | +3. **`opensensor/cache_strategy.py`** |
| 151 | + - Added Fief token caching methods |
| 152 | + - 10-minute TTL for token validation cache |
| 153 | + |
| 154 | +### Security Considerations |
| 155 | + |
| 156 | +- API keys can only access data from their associated device |
| 157 | +- Device ID and name must exactly match the API key registration |
| 158 | +- Fief tokens maintain existing access control logic |
| 159 | +- Cache invalidation on authentication failures |
| 160 | +- No sensitive data stored in cache (tokens are hashed) |
| 161 | + |
| 162 | +### Performance Improvements |
| 163 | + |
| 164 | +- **Reduced Fief Server Load**: Token validation cached for 10 minutes |
| 165 | +- **Faster API Key Validation**: Direct database lookup without external calls |
| 166 | +- **Existing Caching**: Leverages existing Redis caching for data queries |
| 167 | + |
| 168 | +## Testing |
| 169 | + |
| 170 | +Use the provided test script to verify functionality: |
| 171 | + |
| 172 | +```bash |
| 173 | +cd opensensor-api |
| 174 | +python test_flexible_auth.py |
| 175 | +``` |
| 176 | + |
| 177 | +Update the script with your actual API key and device ID before running. |
| 178 | + |
| 179 | +## Migration Notes |
| 180 | + |
| 181 | +- **No breaking changes**: All existing code continues to work |
| 182 | +- **Gradual adoption**: Users can start using API keys when convenient |
| 183 | +- **Monitoring**: Cache hit rates and authentication patterns can be monitored via Redis |
| 184 | + |
| 185 | +## Benefits |
| 186 | + |
| 187 | +1. **Immediate Solution**: Users can export data using existing API keys |
| 188 | +2. **Simple Integration**: Easy to use in scripts and external tools |
| 189 | +3. **Reduced Complexity**: No temporary token management needed |
| 190 | +4. **Better Performance**: Cached authentication reduces server load |
| 191 | +5. **Backward Compatible**: No impact on existing users |
| 192 | + |
| 193 | +## Future Enhancements |
| 194 | + |
| 195 | +Potential future improvements could include: |
| 196 | +- Bulk export endpoints for large data sets |
| 197 | +- API key usage analytics |
| 198 | +- Rate limiting per API key |
| 199 | +- API key expiration dates |
| 200 | +- Scoped permissions for API keys |
| 201 | + |
| 202 | +--- |
| 203 | + |
| 204 | +**Note**: This implementation provides the simplest solution to the immediate problem while maintaining security and performance. The flexible authentication system can be extended in the future as needed. |
0 commit comments