post method rendering 403 forbidden page instead of executing post method code
Asked Answered
D

1

3

note: I am new to Play Framework

Using this video tutorial and playlist, I manage to create a simple webapp.

Problem:

POST methods in routes file do not seem to execute the required POST code.

Given the routes file below, browsing to localhost:{port}/user/register requests a GET, thus rendering and returning the register view.

Filling in the register view fields, and clicking submit, refreshes the page (by clearing the input fields) and does show the expected "registered" text

If method="post" has been added to the form in the register view, an immediate 403 Forbidden page page is displayed.

Why isn't the "registered" text being shown, what am I missing (doing wrong) ?

Routes file:

GET        /                     controllers.HomeController.index

GET        /user                 controllers.LoginController.index()
GET        /user/login           controllers.LoginController.login()
POST       /user/login           controllers.LoginController.doLogin()
GET        /user/register        controllers.LoginController.register()
POST       /user/register        controllers.LoginController.doRegister()

# Map static resources from the /public folder to the /assets URL path
GET        /assets/*file         controllers.Assets.versioned(path="/public", file: Asset)

Controllers:

HomeController
LoginController

LoginController methods:

public Result index() { return ok(views.html.user.index.render(User.getAllUsers())) } 
public Result login() { return ok(login.render()); }
public Result doLogin() { return ok("registered"); }
public Result register() { return ok(register.render()); }
public Result doRegister() { return ok("registered"); }

Register View:

@()

<html>
    <head>
        <title>Register new User</title>
    </head>
    <body>
        <h1>Register User</h1>
        <br>
        <br>
        Enter Email Address: <input type="password" name="confirmPassword">
        Enter Password: <input type="password" name="confirmPassword">
        Confirm Password: <input type="password" name="confirmPassword">
        <br>
        <br>
        <form action="@routes.LoginController.doRegister()">
            <input type="submit" value="Register"/>
        </form>
    </body>
</html>

Console output error:

[warn] p.filters.CSRF - [CSRF] Check failed because no or invalid token found in body
[warn] p.filters.CSRF - [CSRF] Check failed with NoTokenInBody
Domash answered 10/7, 2017 at 17:7 Comment(0)
M
6

I think you're correct you need to define the HTTP method (GET or POST) to be used when submitting the form data.

It's possible you're seen Forbidden because "By default, Play will require a CSRF check" See here?

Add the CSRF token to the request like this:

@import helper._

 <form method="post" action="@CSRF(routes.LoginController.doRegister())">
    ...

Or in the body of the form:

<form method="post" action="@routes.LoginController.doRegister()">
    @CSRF.formField
    ...
Memorialist answered 10/7, 2017 at 23:26 Comment(2)
I did extensive reading up on this topic (filters, etc) to get a beter idea what is causing the issue. I noticed in the documentation, there exists an option to disable the CSRF check for a specific route. This is done by placing ` + nocsrf` above the post route in one's routes file (for every post method one needs bypassing for the CSRF filter. I shall apply your suggested method to include and make use of the CRSF filter, since it was a little vage. Thank you!Domash
@KGCybeX that does work - but is a workaround and removes the safety which the CSRF provides. If you ever deploy, be sure to have the CSRF token in there with the check if you're doing a sensitive POST.Prone

© 2022 - 2024 — McMap. All rights reserved.