Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Framework CSRF error "[CSRF] Check failed because no token found in headers"

I'm new in Play Framework, and trying to submit the form, but get this error: "p.filters.CSRF - [CSRF] Check failed because no token found in headers" . I'm using Play 2.6, here's my controller code:

    package controllers;

import play.libs.Json;
import play.mvc.*;

import views.html.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HomeController extends Controller {

    public Result index() {
        return ok(index.render("Your new application is ready."));
    }

    public Result test() {
        List<String> list = new ArrayList<>();
        list.add("Jobs");
        list.add("Work");
        list.add("Say");
        list.add("Stop");
        return ok(test.render("test", list));
    }

    public Result testPost() {
       Map<String,String[]> form =  request().body().asFormUrlEncoded();
       return ok(Json.toJson(form)).as("application/json");
    }

}

Template:

@(title: String, list: List[String])

@import helper._

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>@title</title>
    </head>
    <body>
        <form action="/test" method="post">
            <textarea name="raw_text">

            </textarea>
            @CSRF.formField
            <input type="submit" value="Submit" />
        </form>
    </body>
</html>

What I am doing wrong?

like image 613
Illia Avatar asked Jul 02 '17 15:07

Illia


Video Answer


2 Answers

By doing Duman Zhanbolatov's answer the error can be avoided but it is not the answer. It will push the app to security flaw.

The reason the application is facing the problem is for the PLAY_SESSION(or your customed session name) cookie of form page request is empty, where csrfToken=value should have been encrypted. Because somehow csrfToken=value in cookies has been removed. It may be happened if you send a response with new-session or discarding cookies. So if you discard cookies or sending response with new-session send it with csrfToken=value session.

def logout: Action[AnyContent] = Action {
    implicit request =>
      val csrfToken = CSRF.getToken.get.value
      
      Ok(logIn("Please log in")).withNewSession.withSession("csrfToken"->csrfToken)

  }  

Then you will get rid of this problem.

Second reason of this problem is: You have run another play application under the domain/localhost/Ip . So the Cookie of that domain/localhost/Ip is still in the cache of browser. When you try to create post req by new play app that cookie is passed into the server, as a result the csrf validation problem occurs. In this case just clear the cookies in browser.

like image 86
John Avatar answered Sep 17 '22 15:09

John


I have faced with it. And i solved it very simply. Just add to your application.conf:

play.filters.enabled += "play.filters.csrf.CSRFFilter"

and in the routes file add the nocsrf modifier tag before your route:

+nocsrf
POST        /login                     controllers.AuthController.authorize()

just like that.. I hope my answer help you. Thank you!

like image 29
Duman Zhanbolatov Avatar answered Sep 16 '22 15:09

Duman Zhanbolatov