Pass value beetween templates

I created CSP for my site but for a test I created nonce with a static string
like this:

add_header Content-Security-Policy "
script-src 'unsafe-inline'
'strict-dynamic' 'nonce-hZwUTOrpRdsdlZmODf631g==';
 style-src 'self' 'unsafe-inline'  'strict-dynamic'

and use it like below:
<script nonce="hZwUTOrpRdsdlZmODf631g==">.....</script>
<style nonce="hZwUTOrpRdsdlZmODf631g==">.....</style>

and I want to create a random string once in my header site and use it several times on elements like style and script
for that, I wrote this function:

def random_string_for_nonce(length) do
      :crypto.strong_rand_bytes(length) |> Base.url_encode64 |> binary_part(0, length)

and call it on app.html.eex file like below:

<%  cspnonce =TrangellHtmlSite.random_string_for_nonce(100) %>

I can use cspnonce on the same page but I can’t pass cspnonce to other templates
how can I do that?

I found one solution

in my app.html.eex file exist this line:

<%= render @view_module, @view_template, assigns %>

and merge my variable into assigns

<%  cspnonce =TrangellHtmlSite.random_string_for_nonce(100) %>
<%= render @view_module, @view_template, Map.merge(assigns, %{cspnonce: cspnonce})  %>

and load it on any template with line below

<script nonce="<%=  assigns.cspnonce %>">... </script>

is my solution correct?

thanks for replies

1 Like

anybody can help me?
is there any better method?

I am not sure what You really want to achieve…

But there are different ways to pass data between html, js, templates.

One simple way would be to set this in the controller, not in the template.

render(conn, "index.html", cspnonce: random_string_for_nonce(100)

# And then use in templates as @csponce

It’s possible to pass data between templates with the same method.

<%= render "name_your_partial.html", cspnonce: @cspnonce, conn: @conn %>

But it seems You want to put this in some js… For this I would put csponce into a data attribute, defined anywhere in your page. It’s easy to read back the value into js.

I would not put logic into templates, I would put this into the controller.

Or You might store this into session? But given I don’t understand why You would do something like this, it’s hard to answer.

I think he wants to use the code concerned which is created in header meta tag and the body on other page, the way you suggested not works well, because the code in header should be equals the code which uses in body in other controller template.

the way you suggested needs to add random code in all controller of his project and it will be painfull, because he has to repeat the code on all controller, for the sake of this problem, I think he needs the way that is created in app.html.eex and other page can get this and use in its html template

Maybe be a plug? That could do the work of extracting header info into conn.assigns?

That is what I do with Phoenix token…