180 lines
4.8 KiB
Markdown
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! 🎉
|