Use case #6: tweaking CSP directives to make AlpineJS work
In my previous use case, I included AlpineJS into my project; but it didn’t work at first try. Indeed, this library needs a few “unsafe” settings in order to work. CSP headers are used to notify the browser that you allow this kind of manipulation.
I didn’t find an official way to modify CSP per slice in the framework, so for the moment I decided to write my own “middleware” to do that. (Note: I know it’s not a real Rack middleware, just an included module with a before hook, but it’s the spirit is the same so that’s why I named it that way. You could definitely do that will a real Rack middleware BTW)
Here is the code of my middleware:
# slices/my_slice/middlewares/set_csp_directives.rb
# auto_register: false
module MySlice
module Middlewares
module SetCSPDirectives
def self.included(action_class)
action_class.before :set_custom_csp_directives
end
def set_custom_csp_directives(request, response)
custom_directives = DEFAULT_CSP_DIRECTIVES.merge(
"script-src" => "'self' 'unsafe-eval'",
"style-src-elem" => "'self' 'unsafe-inline'",
)
response.headers["Content-Security-Policy"] = custom_directives.map do |key, value|
"#{key} #{value}"
end.join(";")
end
# In my real app this constant is defined for my whole project, putting it here for the example
DEFAULT_CSP_DIRECTIVES = {
"base-uri" => "'self'",
"child-src" => "'self'",
"connect-src" => "'self'",
"default-src" => "'none'",
"font-src" => "'self'",
"form-action" => "'self'",
"frame-ancestors" => "'self'",
"frame-src" => "'self'",
"img-src" => "'self' https: data:",
"media-src" => "'self'",
"object-src" => "'none'",
"script-src" => "'self'",
"style-src" => "'self' 'unsafe-inline' https:",
"style-src-elem" => "'self'",
}
end
end
end
I can then include it in my stack, like this:
module MySlice
class Action < MyApp::Action
include MySlice::Middlewares::SetCSPDirectives
include Deps[
"logger",
]
end
end
The browser will then receive these patched CSP on each request, allowing AlpineJS to work properly. ![]()