I have "basic_auth" authentication working for a custom resource post request and now want to add "cookie" authentication. I checked both options on the "Settings for resource" page. But when I try to do the cookie authentication I get
echo '{"foo": "bar"}' | curl -d @- http://localhost/api/RESOURCE?_format=hal_json --header "Content-Type:application/json" --header "X-CSRF-Token:1234" -v
HTTP/1.1 401 Unauthorized
{"message":"No authentication credentials provided."}
If I disable basic_auth and just leave cookie auth do the same request I get
echo '{"foo": "bar"}' | curl -d @- http://localhost/api/RESOURCE?_format=hal_json --header "Content-Type:application/json" --header "X-CSRF-Token:1234" -v
HTTP/1.1 403 Forbidden
{"message":"The \u0027restful post RESOURCE_rest_resource\u0027 permission is required."}
Not sure why I'm getting a different error message but what do I need to do to get cookie auth working? If I go to the People -> Permissions page and enable "Access POST" on my resource for Anonymous users then the curl call works. But that seems to completely bypass any authentication so I don't want that. Here's the call after enabling "Access POST" for anon users:
echo '{"foo": "bar"}' | curl -d @- http://localhost/api/RESOURCE?_format=hal_json --header "Content-Type:application/json" -v
HTTP/1.1 201 Created
Comments
Comment #2
wim leersAre you sending a cookie with your request? I don't see it in your first
curlexample.Comment #3
wim leersComment #4
codesmithI'm sending it as a header:
--header "X-CSRF-Token:1234"That should do it right? I saw this in /core/modules/rest/src/Tests/RESTTestBase.php
Thanks for the help!
Comment #5
wim leersThat's not a cookie, but a CSRF token. When using cookie authentication, you must indeed also send a CSRF token when doing POST/PATCH/DELETE requests (i.e. all requests that make changes), but you still need to send a cookie along with every request as well!
Browsers do this automatically for requests made by JS, but outside a browser, it's up to you!
Comment #6
codesmithAha! Ok for some reason I was equating "cookie authentication" with providing the X-CSRF-Token header. Cookie auth is the cookie provided by the user module after a user logs in. I understand now but this leads me to:
1) If POSTing to a resource requires authentication, why do we need the X-CSRF-Token header?
2) Doesn't actually seem like the X-CSRF-Token is required anyway? I can do a POST with basic auth and not pass the X-CSRF-Token and it works.
3) The REST UI interface requires me to select an "Authentication provider" for POST and DELETE requests. However, if I give the Anonymous User permission to access those methods in the "RESTful Web Services," I can perform the request without authenticating. So seems like there's a disconnect there.
Thanks so much for the help!
Comment #7
codesmithComment #8
wim leers"CSRF" = https://en.wikipedia.org/wiki/Cross-site_request_forgery. Requests made by clients running in a browser automatically include the cookie. So if a malicious user can somehow get a web app (which is written in JS, and runs in a browser) to perform an unsafe (POST/PATCH/DELETE) request by tricking the user of the web app, then you can actually attack them. The browser will NOT know to include additional request headers though. That's why we have this CSRF token request header. Just like we have a CSRF token in HTML forms, for the exact same reason.
See #1891052: Protect write operations from CRSF by requiring an token (when using cookie/session-based authentication), where this was introduced.
Comment #9
wim leers