apoorv-2204

apoorv-2204

Setting Module Attributes in endpoint during compile time for Environment (could not fetch application environment)

Hi there Elixir Community,

IN the phoenix Endpoint, I want to have different session options for dev environment and the production environment, like setting cookie secure, etc.

Issue I am facing is when I use Application.get_env or Application.fetch_env it gives warning and CI fails ,
the Warning: is discouraged in the module body, use Application.compile_env/3 instead

When I use Compile env I get this error.

* (ArgumentError) could not fetch application environment [AdminWeb.Endpoint, :session_options] for application :admin because the application was not loaded nor configured
    (elixir 1.14.4) lib/application.ex:602: Application.compile_env!/3
    lib/admin_web/endpoint.ex:5: (module)
    (elixir 1.14.4) lib/kernel/parallel_compiler.ex:340: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/7
Elixir

I have two apps in umbrella
AdminWeb and ServiceProviderWeb

Code for AdminWeb ,ServiceProvider


defmodule AdminWeb.Endpoint do
  @moduledoc false
  use Phoenix.Endpoint, otp_app: :admin

  @session_options Application.compile_env!(:admin, [__MODULE__, :session_options])

  socket("/admin/live", Phoenix.LiveView.Socket,
    websocket: [connect_info: [session: @session_options]]
  )
#other lines omitted
  plug(Plug.Session, @session_options)
end

defmodule ServiceProvider.Endpoint do
  @moduledoc false
  use Phoenix.Endpoint, otp_app: :service_provider
  @session_options Application.compile_env!(:service_provider, [__MODULE__, :session_options])


  socket("/service_provider/live", Phoenix.LiveView.Socket,
    websocket: [connect_info: [session: @session_options]]
  )

  plug(Plug.Session, @session_options)

end
 

dev.exs

 
config :admin, AdminWeb.Endpoint,
  server: true,
  http: [port: 4001],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: [
    node: [
      "node_modules/webpack/bin/webpack.js",
      "--mode",
      "development",
      cd: Path.expand("../apps/admin/assets", __DIR__)
    ]
  ],
  live_reload: [
    patterns: [
      ~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
      ~r"priv/gettext/.*(po)$",
      ~r"lib/admin_web/.*(ex)$",
      ~r"lib/admin_web/.*(eex)$",
      ~r"lib/admin_web/.*(heex)$"
    ],
    url: "/admin/phoenix/live_reload/socket"
  ],
  session_options: [
    max_age: 120 * 60 * 60,
    store: AdminWeb.Session.Store,
    key: "_a_dev_web_key_",
    signing_salt:  "rand_Contatvalie"
  ]

config :service_provider, ServiceProvider.Endpoint,
  server: true,
  http: [port: 4003],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: [
    node: [
      "node_modules/webpack/bin/webpack.js",
      "--mode",
      "development",
      cd: Path.expand("../apps/service_provider/assets", __DIR__)
    ]
  ],
  live_reload: [
    patterns: [
      ~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
      ~r"priv/gettext/.*(po)$",
      ~r"lib/service_provider/.*(ex)$",
      ~r"lib/service_provider/.*(eex)$",
      ~r"lib/service_provider/.*(heex)$"
    ],
    url: "/service_provider/phoenix/live_reload/socket"
  ],
  session_options: [
    store: :cookie,
    key: "_sp_dev_web_key_",
    signing_salt: "rand_Constant tvallue",
    max_age: 120 * 60 * 60
  ]

Prod.exs

config :admin, AdminWeb.Endpoint,
  cache_static_manifest: "priv/static/cache_manifest.json",
  session_options: [
    max_age: 120 * 60 * 60,
    store: AdminWeb.Session.Store,
    key: "_a_web_key_",
    signing_salt: "random_sallt",
    secure: true,
    http_only: true,
    sign: true
  ]

config :service_provider, ServiceProvider.Endpoint,
  cache_static_manifest: "priv/static/cache_manifest.json",
  session_options: [
    store: :cookie,
    key: "_sp_web_key_",
    signing_salt: "random_sallt",
    max_age: 120 * 60 * 60,
    secure: true,
    http_only: true,
    sign: true,encrypt: true
  ]
`My questions`

Q1. What is the solution for it, what mistake I am making?.What wrong settings I have done here?
Q2. Are dev.exs and prod.exs executed once on compilation? so can i use `Base.encode64(:crypto.strong_rand_bytes(64), padding: false)` for `signing_salt`.
Q3. what are the generral best practices tips that you guys can share?

Most Liked

gushonorato

gushonorato

Hey @apoorv-2204

Q1. What is the solution for it, what mistake I am making?.What wrong settings I have done here?

The problem is that Application.compile_env!/3 does not accept a list as an argument. Instead, you should do the following: @session_options Application.compile_env!(:admin, ServiceProvider.Endpoint) |> Keyword.fetch!(:session_options)

Q2. Are dev.exs and prod.exs executed once on compilation? so can i use Base.encode64(:crypto.strong_rand_bytes(64), padding: false) for signing_salt.

You must not use Base.encode64/2 to generate the signing_salt in this way. If you do so, a new signing_salt will be generated with each deployment, and all sessions will be invalidated in production every time the application is deployed.

Q3. what are the generral best practices tips that you guys can share?

You can use any signing_salt for development and store it hardcoded in your dev.exs file. However, for production, it is not recommended to store the signing_salt hardcoded in version-controlled files. Instead, store it as an environment variable and load it in config/runtime.exs.

# config/runtime.exs

signing_salt = 
  System.get_env("SESSION_SIGNING_SALT") || 
    raise "SESSION_SIGNING_SALT environment variable is not set"

config :admin, AdminWeb.Endpoint,
  session_options: [
    max_age: 120 * 60 * 60,
    store: AdminWeb.Session.Store,
    key: "_a_dev_web_key_",
    signing_salt: signing_salt
  ]

Where Next?

Popular in Discussions Top

blackode
Elixir Upgrading is so Simple in Ubuntu and It worked for me Ubuntu 16.04 git clone https://github.com/elixir-lang/elixir.git cd elixir...
New
MarioFlach
Hello, I want to share a project I’ve been working on for a while: https://github.com/almightycouch/gitgud Background Some time ago I ...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
AstonJ
If a newbie asked you about Phoenix Contexts, how would you explain the basics to them? Feel free to be as concise or in-depth as you li...
New
Ankhers
Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in...
New
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
100phlecs
Are there any downsides, like perf issues, to putting all functional components in CoreComponents as long as you prefix it with the conte...
New
wmnnd
The Go vs Elixir thread got me thinking: Would it be too hard to implement a simple mechanism for creating Go-style static app binaries f...
New
pdgonzalez872
If this has been asked here before, please point me to where it was asked as I didn’t find it when I searched the forum. Maybe a mailing ...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 47930 226
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement