Files
MySMSAPio/SESSION_MIDDLEWARE_FIX.md
2025-10-22 17:22:17 +08:00

180 lines
4.8 KiB
Markdown

# Session & Flash Middleware Fix
## Issue
```
undefined method 'flash' for an instance of ActionDispatch::Request
```
This error occurred because the application was configured as **API-only mode** (`config.api_only = true`), which disables session and flash middleware by default. However, the admin interface needs these features for:
- Session-based authentication
- Flash messages (success/error notifications)
- CSRF protection
## Solution
Manually include the required middleware in the application configuration while keeping API-only mode for the API endpoints.
## Changes Made
### 1. Updated Application Configuration
**File:** `config/application.rb`
Added middleware explicitly:
```ruby
# Configure API-only mode (but keep session middleware for admin interface)
config.api_only = true
# Include session and flash middleware for admin interface
# Even though this is an API-only app, we need sessions for the admin UI
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore
config.middleware.use ActionDispatch::Flash
```
### 2. Updated Admin Base Controller
**File:** `app/controllers/admin/base_controller.rb`
Added CSRF protection:
```ruby
module Admin
class BaseController < ActionController::Base
include Pagy::Backend
# Enable session and flash for admin controllers
# (needed because the app is in API-only mode)
protect_from_forgery with: :exception
layout "admin"
before_action :require_admin
# ...
end
end
```
## Why This Works
### API-Only Mode Benefits (Kept)
- ✅ Faster API responses (no session overhead for API endpoints)
- ✅ RESTful API design
- ✅ No unnecessary middleware for API calls
- ✅ Better performance for mobile/external clients
### Admin Interface Benefits (Added)
- ✅ Session-based authentication
- ✅ Flash messages for user feedback
- ✅ CSRF protection
- ✅ Cookie support for "remember me" features
- ✅ Standard Rails web app behavior
### How Both Coexist
1. **API Controllers** (`ApplicationController < ActionController::API`)
- Don't use sessions or flash
- Use token-based authentication
- Remain lightweight and fast
2. **Admin Controllers** (`Admin::BaseController < ActionController::Base`)
- Use sessions and flash
- Use cookie-based authentication
- Full Rails web app features
## Architecture
```
Rails Application (API-only mode)
├── API Controllers (ActionController::API)
│ ├── /api/v1/sms
│ ├── /api/v1/otp
│ └── /api/v1/gateway/*
│ └── Uses: Token auth, JSON responses
└── Admin Controllers (ActionController::Base)
├── /admin/login
├── /admin/dashboard
├── /admin/api_keys
├── /admin/logs
└── /admin/gateways
└── Uses: Session auth, HTML responses, flash messages
```
## Middleware Stack
Now includes (in order):
1. `ActionDispatch::Cookies` - Cookie handling
2. `ActionDispatch::Session::CookieStore` - Session storage
3. `ActionDispatch::Flash` - Flash messages
These are available to **all** controllers, but only admin controllers use them.
## Verification
Check middleware is loaded:
```bash
bin/rails middleware | grep -E "(Session|Flash|Cookies)"
```
Should output:
```
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
```
Test application:
```bash
bin/rails runner "puts 'AdminUser: ' + AdminUser.first.email"
```
## Security Considerations
### CSRF Protection
- ✅ Enabled for admin controllers via `protect_from_forgery with: :exception`
- ✅ Automatically includes CSRF token in forms
- ✅ Validates token on POST/PUT/PATCH/DELETE requests
### Session Security
- ✅ Uses encrypted cookie store
- ✅ Session expires when browser closes (default)
- ✅ Session data is signed and verified
### Cookie Settings
Default configuration uses secure cookies in production:
- HttpOnly: Yes (prevents XSS)
- Secure: Yes in production (HTTPS only)
- SameSite: Lax (prevents CSRF)
## No Impact on API
The API endpoints remain unchanged:
- ✅ No session overhead
- ✅ No CSRF checks
- ✅ Token-based authentication still works
- ✅ Same performance characteristics
## Testing
### Test Admin Login
```bash
# Start server
bin/rails server
# Visit in browser
open http://localhost:3000/admin/login
```
### Test API Endpoint
```bash
# Should work without sessions
curl -H "Authorization: Bearer your_api_key" \
http://localhost:3000/api/v1/sms/received
```
## Summary
**Fixed**: Flash messages work in admin interface
**Fixed**: Sessions work for authentication
**Kept**: API-only mode for API endpoints
**Kept**: Performance benefits of API-only
**Added**: CSRF protection for admin
**Added**: Cookie support for admin
Both the API and admin interface now work correctly side-by-side! 🎉