Phoenix中通过Plug设置csp_nonce_assign_key为Map时出现Phoenix.HTML.Safe错误
解决Phoenix Live Dashboard CSP Nonce使用Plug时的Map报错问题
问题根因
你遇到的问题核心在于两种设置方式的逻辑差异:
- 直接在
router.ex里把Map传给csp_nonce_assign_key时,Live Dashboard会直接读取Map中的字符串nonce值,而字符串本身已经实现了Phoenix.HTML.Safe协议,所以不会报错。 - 当
csp_nonce_assign_key设为原子(比如:csp_nonce_value)时,Live Dashboard会从conn的assign中取出对应的值,然后尝试将这个值当作可安全渲染的内容处理——但你传入的是Map,而Map并没有实现Phoenix.HTML.Safe协议,因此触发了报错。
解决方案
正确的做法是让csp_nonce_assign_key的Map指向conn中单独的assign原子,而非直接传入一个Map类型的assign值:
1. 修改router.ex配置
live_dashboard "/dashboard", csp_nonce_assign_key: %{ img: :img_nonce, style: :style_nonce, script: :script_nonce }
2. 更新Plug代码
# my_plug.ex def call(conn, _opts) do conn |> assign(:img_nonce, generate_nonce()) |> assign(:style_nonce, generate_nonce()) |> assign(:script_nonce, generate_nonce()) end
这样设置后,Live Dashboard会分别从conn的assign中取出每个原子对应的字符串nonce,而字符串天然支持Phoenix.HTML.Safe,就能正常生成CSP头了。
补充说明
Phoenix的Phoenix.HTML.Safe协议用于确保内容在插入HTML或响应头时不会引发注入风险。字符串、整数等基础类型都默认实现了这个协议,但Map没有——因为Map的结构不确定,无法自动安全处理。这就是为什么直接传Map类型的assign会报错的原因。
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

