如何在运行时设置Phoenix Plug.Session的secure属性值?(Elixir 12 + Erlang 24环境)
解决Phoenix Plug.Session secure属性运行时动态配置的问题
没问题,我帮你搞定这个编译时vs运行时的配置问题!你现在的写法里,secure: System.get_env(...) == "true"会在编译阶段就确定值,之后哪怕环境变量变化,这个配置也不会更新。要改成运行时动态获取,有两种实用方案:
方案一:利用Phoenix运行时配置(推荐,简洁规范)
Phoenix 1.6+支持config/runtime.exs文件,专门用来处理运行时才需要解析的配置,正好适合你的场景:
- 先在
config/runtime.exs里添加session的动态配置:
# config/runtime.exs config :my_app, :session_secure, System.get_env("PLUG_SESSION_SECURE", "true") == "true"
(把my_app换成你的实际应用名)
- 修改
lib/my_app_web/endpoint.ex里的Plug.Session配置,从应用环境中读取secure值:
# lib/my_app_web/endpoint.ex plug Plug.Session, store: :cookie, key: "_key", signing_salt: "KahwH24", max_age: 60 * 60, secure: Application.get_env(:my_app, :session_secure, true)
这样,session_secure的值会在应用启动时读取环境变量,而不是编译时。如果你的环境变量在运行中不会变动,这个方案完全够用,而且符合Phoenix的配置最佳实践。
方案二:自定义Plug封装(更灵活)
如果需要更灵活的控制(比如极端情况下要在每次请求时重新读取环境变量),可以自己写一个简单的Plug来封装Plug.Session,在初始化阶段动态计算secure值:
- 创建自定义Plug模块:
# lib/my_app_web/plugs/session_plug.ex defmodule MyAppWeb.SessionPlug do @moduledoc "动态配置Session的secure属性" import Plug.Conn def init(opts) do # 在这里动态获取最新的环境变量值 secure = System.get_env("PLUG_SESSION_SECURE", "true") == "true" # 合并到原始配置中,再调用Plug.Session的初始化方法 updated_opts = Keyword.put(opts, :secure, secure) Plug.Session.init(updated_opts) end def call(conn, opts) do # 直接调用原Plug.Session的处理逻辑 Plug.Session.call(conn, opts) end end
- 在
endpoint.ex里替换原来的Plug.Session:
# lib/my_app_web/endpoint.ex plug MyAppWeb.SessionPlug, store: :cookie, key: "_key", signing_salt: "KahwH24", max_age: 60 * 60
这个方案的优势是可以在init/1甚至call/2里做更复杂的逻辑(比如根据请求域名、环境动态调整secure),适合特殊场景。
注意事项
- 如果你用的是较旧的Phoenix版本(低于1.6),没有
runtime.exs的话,可以把运行时配置放到config/prod.exs里,但要确保部署时这个文件是在运行时解析的(比如用Distillery或者Mix release的话,默认会处理)。 - 一般来说,环境变量在应用启动后不会变动,所以两种方案都能满足需求,推荐优先用方案一,更简洁。
内容的提问来源于stack exchange,提问作者kk k
相关产品推荐
相关产品推荐

