Sessions
Amber exposes session and flash directly inside a controller. Amber CLI's
V2 web template enables the session and flash pipes in this order.
File: config/routes.cr — keep this order inside the generated pipeline :web block.
pipeline :web do
plug Amber::Pipe::Error.new
plug Amber::Pipe::Logger.new
plug Amber::Pipe::Session.new
plug Amber::Pipe::Flash.new
plug Amber::Pipe::CSRF.new
end
Keep Session before Flash: flash messages are serialized through the
session after the request.
Generated configuration
The web template writes the following section to each environment YAML file.
Files: config/environments/development.yml,
config/environments/test.yml, and config/environments/production.yml — edit
the existing session: section in each environment rather than adding a
duplicate key.
session:
key: my_app.session
store: signed_cookie
adapter: memory
expires: 0
The V2 session store uses the configured adapter for session values and an
encrypted cookie for the session identifier. The built-in memory adapter is
useful for local development and tests, but its data is process-local. Choose a
shared custom adapter before running multiple application processes or before
depending on sessions that must survive a restart. See Session
Adapters.
Production also requires a long AMBER_SERVER_SECRET_KEY_BASE; Amber uses it
to protect cookies. Do not commit a production secret to the YAML file.
Read, write, and delete values
Session keys accept strings or symbols. Values are stored as strings.
File: src/controllers/logins_controller.cr — place these actions inside
LoginsController, then register their routes in config/routes.cr.
class LoginsController < ApplicationController
def create
# Replace this lookup with your application's authentication logic.
user_id = "42"
session[:current_user_id] = user_id
# Regenerate an adapter-backed session ID after authentication to prevent
# session fixation. This is a no-op for a cookie-only store.
context.regenerate_session!
flash.notice = "Welcome back."
redirect_to location: "/", status: 302
end
def destroy
session.delete(:current_user_id)
flash[:notice] = "You have signed out."
redirect_to location: "/", status: 302
end
end
File: the controller action that needs the authenticated identity — use the optional lookup where absence is expected.
if user_id = session[:current_user_id]?
# Load the user through the persistence layer selected by the application.
end
Keep session payloads small and non-sensitive. Store a stable identifier, not an entire model or authorization policy, and verify authorization again on every protected request.
Flash messages
Flash values are intended for the next request. Reading a value marks it for
removal; keep carries it forward, while now makes a value available only in
the current request.
File: the controller action that sets the message.
flash[:error] = "Please correct the highlighted fields."
flash.keep(:error)
flash.now(:notice, "The preview was not saved.")
File: src/views/layouts/_flash.ecr — create this reusable partial, then
render it from src/views/layouts/application.ecr.
<% flash.each do |name, message| %>
<div class="flash flash-<%= name %>"><%= message %></div>
<% end %>
File: src/views/layouts/application.ecr — add this call where global
messages should appear.
<%= render(partial: "layouts/_flash.ecr") %>
The V1 guide's inline Redis configuration is not a V2 configuration contract.
Implement and register a session adapter instead, then select it with the
session.adapter setting.