4.8 KiB
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:
# 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:
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
-
API Controllers (
ApplicationController < ActionController::API)- Don't use sessions or flash
- Use token-based authentication
- Remain lightweight and fast
-
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):
ActionDispatch::Cookies- Cookie handlingActionDispatch::Session::CookieStore- Session storageActionDispatch::Flash- Flash messages
These are available to all controllers, but only admin controllers use them.
Verification
Check middleware is loaded:
bin/rails middleware | grep -E "(Session|Flash|Cookies)"
Should output:
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
Test application:
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
# Start server
bin/rails server
# Visit in browser
open http://localhost:3000/admin/login
Test API Endpoint
# 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! 🎉