santoshbt

santoshbt

I a in a similar situation as this post owner. I have an API only app which has to produce the csrf token by get_csrf_token() and pass it on to angular app. Currently I am trying ot make a post request via Postman. I have set this token generated in header X-CSRF-Token or passing through parameter like _csrf_token. But always getting Invalid token InvalidCSRFTokenError.

0
Post #11
voger

voger

For some reason, when you go through the API route, the _csrf_token key is missing from the session or set to the masked value. I don’t remember since has been a while since I had this problem. The way I made it work is create an endpoint where the app can get a new CSRF token and that endpoint sets the _csrf_token key in the session to the unmasked value

def show(conn, _) do
    csrf_token = Plug.CSRFProtection.get_csrf_token()

    conn
    |> fetch_session()
    |> put_session("_csrf_token", Process.get(:plug_unmasked_csrf_token))
    |> render("show.json", token: csrf_token)
  end

The idea is that each time you create a new CSRF token, you put the masked value in the session. I hope this helps.

0
Post #12
santoshbt

santoshbt

Thanks for your help.

I have put plug :protect_from_forgery in routes
and in some controller

def csrf_token(conn, _params) do
    csrf_token = Plug.CSRFProtection.get_csrf_token
    conn
    |> fetch_session()
    |> put_session("_csrf_token", Process.get(:plug_unmasked_csrf_token))
    |> put_view(MyAppWeb.APIV2.UserView)
    |> render("session_token.json", token: csrf_token)
  end

For the first service request, it recognized the csrf token and worked properly.
But subsequent request it is getting the same Invalid CSRF token error.
Even I generated the new token, but not able to succeed.

Also please let me know, when this token will get cleared off, if it works in subsequent requests?

Please help on this.
TIA..

0
Post #13
voger

voger

I just tested it and it works as it should. I am not using Postman. I use Insomnia or RESTer for Firefox.

What I do is contact the token generating endpoint e.g.: http://localhost:4000/api/token which returns a json like

{
  "token": "VxIYVQMwHXIAAFcGISBcEBsRchA-AmAhcYZgkqp4mr6nNM2hhdBcxTUl"
}

I put that token in every request I want to make to the server in the x-csrf-token header and it works fine. If I contact again that endpoint it will return a new token and I will have to update the header in all the requests because the old token is now invalid.

Maybe there is some problem with the cookies, session or maybe the app contacts often the token endpoint and doesn’t update the requests header.

I would suggest you inspect the conn struct in the failing controller, once when it succeeds and once when it fails. Look under the req_headers key if there is any "x-csrf-token" tuple and if it’s value is the same both times.

Also check under the :private key for :plug_session => %{"_csrf_token" => "lfiUShv-j1sI5Q4z20k7B-WD"} and if the _csrf_token value remains the same.

0
Post #14
santoshbt

santoshbt

I found the major difference in :private key for :plug_session.
For succeeding request it is :plug_session => %{“_csrf_token” => “dYmLXL3R1plGyrLaFjyriM2U”},
For failing request is is :plug_session => %{},

Also with Postman, atleast we are able to get the First response working.
With RESTer for chrome, none of the requests are recognizing the csrf token.

Thanks

0
Post #15
— All posts loaded —