Adding Simple Form in Phoenix Application

I have a simple html page with a form.

Whenever I try to submit the form I get the error

Plug.CSRFProtection.InvalidCSRFTokenError at POST /
invalid CSRF (Cross Site Request Forgery) token, make sure all requests include a valid ‘_csrf_token’ param or ‘x-csrf-token’ header

Router :
scope “/”, TestWebAppWeb do
pipe_through :browser # Use the default browser stack
resources “/”, PageController
end

Controller :
def create(conn, _params) do

IO.puts "Getting POST data"
render conn, "index.html"

end

Any way of getting rid of this error?

I am assuming it is some template function that has to be added but I am not sure and I can’t find any examples online of a simple form that is sent to a server and handled by a phoenix without using ecto.

Thanks in advance

By default, your :browser pipeline plugs :protect_from_forgery which is what gives you CSRF protection, and also is the source of the exception you’re seeing. Instead of ditching CSRF protection, you can create simple forms by passing a %Plug.Conn{} to the form_for builder, for example:

<%= form_for @conn, session_path(@conn, :create), as: "session", fn f ->
  <%= text_input f, :username %>
  ...
<% end %>

Thanks for your reply,

I added the following code to the
<%= form_for @conn, session_path(@conn, :create), [as: :session], fn f -> %>
<%= text_input f, :username %>
<% end %>

But now I am getting the following stating that session_path/2 is underfined
== Compilation error in file lib/test_web_app_web/views/page_view.ex ==
** (CompileError) lib/test_web_app_web/templates/page/index.html.eex:21: undefined function session_path/
2
(stdlib) lists.erl:1338: :lists.foreach/2
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(elixir) lib/kernel/parallel_compiler.ex:168: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers
/1

I tried creating this function in both the specific controller and the router, but have come to the conclusion that this is some internal function to phoenix,.

So are there any libraries that I should include to make the function visible to the compiler?

Thanks in advance

That’s a function set in the router file, to indicate the path to which that particular form should send its submission

If you add this to your router.ex file, inside the scope

 scope "/", YourAppName do
    pipe_through :browser

    get    "/login",  SessionController, :new
    post   "/login",  SessionController, :create
    delete "/logout", SessionController, :delete

    #existing stuff...
end

And then from the terminal on your app folder do:
mix phoenix.routes
(or mix phx.routes)

You should see 3 new routes for your app, ie:

session_path  GET      /login                          YourAppName.SessionController :new
session_path  POST     /login                        YourAppName.SessionController :create
session_path  DELETE   /logout                    YourAppName.SessionController :delete

As you can see it maps, 3 different verbs you set on the router, to 3 different actions in a controller and creates the function by prepending the controller name to _path

You’ll also need to create a controller that will take the form submission and do whatever action is required with that information (such as signing the user in). So in this case you would create a Session controller with 3 functions, new, create and delete

You can create whatever controller you want and use that instead, and the resulting *_path will reflect the name you chose. I would suggest you to read the docs on phoenix as I think all of that is covered there.

Thanks for your reply

the *_path where * matches the name of the controller was where I was going wrong.

My controller is called PageController so I call form with page_path/2.

full example for anyone else who gets stuck with this error

<%= form_for @conn, page_path(@conn, :handlePost), [as: :session], fn f -> %>
<%= text_input f, :username %>
<% end %>