Backend CakePHP 3.6 REST , frontend React
Request
Request URL: http://localhost/restcake/v1/posts.json
Request Method: POST
Status Code: 400 Bad Request
Remote Address: [::1]:80
Referrer Policy: no-referrer-when-downgrade
Reponse
code: 400
file: “PATHTO\vendor\cakephp\cakephp\src\Controller\Component\SecurityComponent.php”
line: 351
message: “’_Token’ was not found in request data.”
url: “/v1/translations.json”
Request header
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,mn-MN;q=0.8,mn;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 68
Content-Type: application/json
Cookie: csrfToken=1ca4d0479b6721049b17fa879e269816515cdd216e2f0a85a828dad33fa2bacf3a341f74b7d08b75ffa3b9fbebd0219914d50d30e6abeec45129c2fe39e1f7fa; CAKEPHP=pv2nkumt1a32urftf2jvq5nrrm; remember_me=Q2FrZQ%3D%3D.ZGYyNDNiMjdkOTRlNDMyZGVjYzhkMWUwZTE4MTJhOWJjZjBkZjEzODA5MWE2ZjJkOWRhN2RkNTg0ZjEwZDM4ML2ESQrHcOqYaNiMcRSYoK4WcuCAPx%2Fz7UgmA6cBU6pZXYnQX29kT2zUhGDCVlU%2F0ZPjlHtX7qiyIsuEwiCrmBonaNBD6G8QL4WMgap2QOieQ6KV%2BnQjRKz%2FYvzyuxwcia7ChJNdcvy1%2B9UzCSSLWX%2BDBR%2F1Qivlvc0Dl1HL6tX%2BaWWc6IfoT82wS331XCMUzcIo0yQzyVp595PkT%2F8NjXtyK3M%2BeB5bKy%2FMYCAIrXLJWVCse9NYACix35fST0unQ69FBxihlu0Wli%2BAT3NGQWo%3D
Host: localhost
Origin: http://localhost:4000
Pragma: no-cache
Referer: http://localhost:4000/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36
I temporary disabled CORS in middleware.
Related
We're developing a website with a REST Api (frontend in AngularJS 1.6.1, backend in Laravel 5.3).
In order to add CSRF protection, our backend needs to set a backend cookie on the client with a random string. In laravel, we return this response:
response("OK", 200)->cookie("csrf_token", "random_string");
The cookie is clearly being set with the response:
*Request headers*
POST /v1/auth/admin HTTP/1.1
Host: backend.test
Connection: keep-alive
Content-Length: 295
Accept: */*
Origin: http://frontend.test
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://frontend.test/login
Accept-Encoding: gzip, deflate
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
*Response header*
HTTP/1.1 200 OK
Server: nginx/1.11.3
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: http://frontend.test
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, PATCH
Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Requested-With
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Date: Mon, 13 Feb 2017 11:46:16 GMT
Set-Cookie: csrf_token=random_string; expires=Sat, 12-Feb-2022 11:46:16 GMT; Max-Age=157680000; path=/; domain=http://backend.test; HttpOnly
However, when I go to the http://backend.test Url, no cookie is set (document.cookie in the console returns null).
The backend cannot see the cookie either: dd($request->cookie("csrf_token") returns null.
It doesn't work even if we omit the domain. Any ideas?
For Angular to send the cookie along with the request in a CORS (Cross Origin Resource Sharing request), you need to set, in your config with $httpProvider injected as a dependency:
.config(function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
//rest of route code
}
When you use Laravel you do not have to set the csrf cookie by yourself. Laravel automatically does this job for you.
So laravel creates automatically a cookie to store the csrf token. The name of that cookie is "XSRF-TOKEN".
I have this little angular app on the frontend which is a food list. So write a food and click submit and it will show the list.
When I add a food I query my backend wich is a sails app at localhost:1337 and it gets updated. The problem is I get redirected to
localhost:9000/#/food and get 404.
This is the faulty request
POST / HTTP/1.1
Host: localhost:9000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image /webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Content-Type: application/x-www-form-urlencoded
Cookie:sails.sid=s%3A8gIjNxaZVE9dMr7nonXJzEaQ9hUcvcHm.Sp0K6ezep%2F7Y%2BV6TivtdRxqiBV 2S1LdH2IDNPWS9Ikk
Origin: http://localhost:9000
Referer: http://localhost:9000/
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id: 137B2031-138E-4B6B-A3AE- FB8EE96E9015
HTTP/1.1 404 Not Found
Connection: keep-alive
content-length: 14
Content-Type: text/html; charset=utf-8
Date: Mon, 23 Feb 2015 12:21:51 GMT
X-Content-Type-Options: nosniff
The other request that gets code 200 and update the server model looks like this:
OPTIONS /food HTTP/1.1
Host: localhost:1337
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers: accept, content-type
Access-Control-Request-Method: POST
Origin: http://localhost:9000
Referer: http://localhost:9000/
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id: 137B2031-138E-4B6B-A3AE- FB8EE96E9015
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type, access-control-allow-origin, authorization,X-Requested-With
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin: http://localhost:9000
Allow: GET,POST,PUT,HEAD,DELETE,TRACE,COPY,LOCK,MKCOL,MOVE,PURGE,PROPFIND,PROPPATCH, UNLOCK,REPORT,MKACTIVITY,CHECKOUT,MERGE,M- SEARCH,NOTIFY,SUBSCRIBE,UNSUBSCRIBE,PATCH,SEARCH,CONNECT
Connection: keep-alive
Content-Length: 175
Content-Type: text/html; charset=utf-8
Date: Mon, 23 Feb 2015 12:21:51 GMT
set-cookie: sails.sid=s%3A_kBdyRZgZ23Gh9YLkZfWBgnMody- jq-S.IY71%2BhJiBxTd19YIG2tgS2EOn1LPT%2BD9QAEQWtVB%2FbE; Path=/; HttpOnly
X-Powered-By: Sails <sailsjs.org>
At first I was looking at sails but I have CORS enabled and everything just like this:
https://github.com/tarlepp/angular-sailsjs-boilerplate/blob/master/backend/config/cors.js
So maybe it's more an angular issue. The request that fails is from the frontend to itself so just a redirect on itself when it has been updated on the server. I don't get why the request is denied...
If you want to take a look at the code:
http://okamuuu.hatenablog.com/entry/2014/04/10/135240
Issues seem the same as this Yeoman, Grunt, AngularJS and error 404 on POST form but that doesn't help me
Well, apparently your request is going to the port 9000:
Host: localhost:9000
Yet you said your app is running at port 1337.
So, in your $http requests, you need to specify the port. Otherwise, it will use the port your browser is currently connected to (9000) and there's no app there!
So, instead of
$http.get('/someUrl')
Try
$http.get('http://localhost:1337/someUrl')
I have a node/express aplication with CORS enabled
When I do POST /login to my app does a redirect to /failure or /success
but always a i get a
XMLHttpRequest cannot load http://exampledomain.com/login. The request was redirected to 'http://exampledomain.com/success', which is disallowed for cross-origin requests that require preflight.
the $http do two requests to the server
OPTIONS request
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://otherdomain.com
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,PUT,POST,PATCH,DELETE
Access-Control-Allow-Headers: accept, content-type
Connection: keep-alive
Options response
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://otherdomain.com
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,PUT,POST,PATCH,DELETE
Access-Control-Allow-Headers: accept, content-type
Connection: keep-alive
POST request
POST /admin/login HTTP/1.1
Host: exampledomain.com
Connection: keep-alive
Content-Length: 43
Accept: application/json, text/plain, */*
Origin: http://otherdomain.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2267.0 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://otherdomain.com
Accept-Encoding: gzip, deflate
Accept-Language: es-419,es;q=0.8
POST response
HTTP/1.1 302 Moved Temporarily
Vary: X-HTTP-Method-Override, Origin, Accept
Access-Control-Allow-Origin: http://otherdomain.com
Access-Control-Allow-Credentials: true
Location: /success
Content-Type: text/plain; charset=utf-8
Content-Length: 45
set-cookie: cookie-data; Path=/; HttpOnly
Connection: keep-alive
I think the headers are correct but something is missing about the Location header. Can help me with this
I'm doing the request with $http like follows
$http.defaults.useXDomain = true;
$http.post('http://exampledomain/login', {
username: 'user',
password: 'pass'
}).success(...).error(...)
but the success is never called
CORS is not enabled for http://exampledomain.com, thus no requests can be made to it. In fact the browser does a preflight check and since it fails the requests are not actually sent to the server at all.
The only way to change this is to enable CORS on the server for your domain.
I'm writing a simple webserver and right now I'm just trying to set up a generic
response to see that it's working. Right now, it's only been working on Firefox and not
on Chrome or Opera. Below are some of the requests I've gotten and a generic response is at the end. Is there a line I'm missing in the response? Is there really a generic response to get the server up and running?
I see that the requests have "Connection: keep-alive", so I tried leaving the connection open for a few seconds, and that didn't seem to help. I tried sending the data separately from the response header and that didn't really help either.
GET / HTTP/1.1
Host: 192.168.1.128
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
GET / HTTP/1.1
User-Agent: Opera/9.80 (X11; Linux x86_64) Presto/2.12.388 Version/12.15
Host: 192.168.1.128
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
GET / HTTP/1.1
Host: 192.168.1.128
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Response here:
HTTP/1.0 200 OK
Date: Sun Apr 14 15:13:36 2013
Server: server_th
Content-Type: text/html
Content-Length: 40
Connection: close
<html><body><h3>Hey!</h3></body></html>
Your response has no body, so you will see a blank page. Besides, it seems to be lacking the trailing CRLF, but I am not sure whether it is due to copy-paste.
Check the HTTP specs.
EDIT: in the updated response, body length is actually 39, although it is declared 40. could it be that the client is waiting for remaining payload?
I'm using blobstore to serve audio files embedded in HTML5 audio element. Because I have a blobkey as a part of url I can assume that for any given url its content will never change. That looks like a perfect setup for caching.
Yesterday I implemented a solution which seemed to work. At least I remember that it worked ;). Unfortunately today I discovered, that it doesn't work with Chrome and production server. It works perfectly with Internet Explorer and Firefox. It even works with Chrome and development server - I use version 1.7.6. My solution uses Cache-Control headers, but it seems that only Firefox makes any use of it. Additionally I added an ETag header. When I discover If-None-Match request header with the same value I return 304 code. That seems to work with Internet Explorer. It also works with Chrome and development server. I remember that it had worked yesterday with Chrome and production, but I'm not completely sure. Anyway the problem I have is why both caching mechanisms are ignored by Chrome. I suspect that it may have something to do with chunked encoding which is generated only for chrome, but I don't understand why caching is disabled in that case
And now a lot of details.
Firefox
Initial request headers:
Host: eduzabawy.appspot.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5
Accept-Language: pl,en-us;q=0.7,en;q=0.3
Range: bytes=0-
Referer: http://eduzabawy.appspot.com/dziecko/
Cookie: children="jEDor1B8VRDRJreWmUVlUQ\075\075"; session=eyJfc2lkIjoiWk91QmlsOEJlTEd4QVFuYVFiYkpsTyJ9|1365190508|81d81772f6f409dd57ad43a9f447f92d1b56d29e
Connection: keep-alive
Initial response headers:
HTTP/1.1 206 Partial Content
Cache-Control: public max-age=100000000
Content-Range: bytes 0-37249/37250
Content-Type: audio/ogg
Date: Fri, 05 Apr 2013 19:45:47 GMT
Etag: blobstore
Server: Google Frontend
X-Firefox-Spdy: 3
On subsequent loads it seems that Firefox doesn't even try to fetch the files. This is how I thought it should work.
Internet Explorer
Initial request headers:
Accept: */*
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Referer: http://eduzabawy.appspot.com/dziecko/
Accept-Language: pl-PL
Accept-Encoding: gzip, deflate
Host: eduzabawy.appspot.com
Connection: Keep-Alive
Cookie: children="WyzUQwHEzwX6qnjfn21KEw\075\075"; session=eyJfc2lkIjoia2VOd0llR0hvRHU1cUN0cE1QSWRpWCJ9|1365192921|f2279f82b21947c4d064dbf44a5ce9e1bd95cc0d
Initial response headers:
HTTP/1.1 200 OK
Cache-Control: public max-age=100000000
ETag: blobstore
Content-Type: audio/mpeg
Date: Fri, 05 Apr 2013 20:15:23 GMT
Server: Google Frontend
Content-Length: 4637
Subsequent request headers:
Accept: */*
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Referer: http://eduzabawy.appspot.com/dziecko/
Accept-Language: pl-PL
Accept-Encoding: gzip, deflate
Host: eduzabawy.appspot.com
If-None-Match: blobstore
Connection: Keep-Alive
Cookie: children="WyzUQwHEzwX6qnjfn21KEw\075\075"; session=eyJfc2lkIjoia2VOd0llR0hvRHU1cUN0cE1QSWRpWCJ9|1365192921|f2279f82b21947c4d064dbf44a5ce9e1bd95cc0d
Subsequent response headers:
HTTP/1.1 304 Not Modified
ETag: blobstore
Content-Type: audio/mpeg
Content-Length: 4637
Chrome + development server
Initial request headers:
Host: localhost:8080
Connection: keep-alive
Accept-Encoding: identity;q=1, *;q=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Accept: */*
Referer: http://localhost:8080/dziecko/
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.3
Cookie: children="xYNsqzfdtZ-2Z764lFSzk1Ed8-g1QoNlcaexsD79gSY\075"; session=eyJfc2lkIjoiTE9CZDc0SHJENHF4OWJua1J4S3dTQSJ9|1365192253|37815772acab0bf44a0c501ea0fd0dc7c617dd09
Range: bytes=0-
Initial response headers:
HTTP/1.1 206 Partial Content
etag: blobstore
cache-control: public max-age=100000000
content-type: audio/mpeg
Content-Range: bytes 0-4636/4637
Content-Length: 4637
Server: Development/2.0
Date: Fri, 05 Apr 2013 20:32:19 GMT
Subsequent request headers:
Host: localhost:8080
Connection: keep-alive
Accept-Encoding: identity;q=1, *;q=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Accept: */*
Referer: http://localhost:8080/dziecko/
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.3
Cookie: children="xYNsqzfdtZ-2Z764lFSzk1Ed8-g1QoNlcaexsD79gSY\075"; session=eyJfc2lkIjoiTE9CZDc0SHJENHF4OWJua1J4S3dTQSJ9|1365192253|37815772acab0bf44a0c501ea0fd0dc7c617dd09
Range: bytes=0-4636
If-None-Match: blobstore
Subsequent response headers:
HTTP/1.1 304 Not Modified
Content-Type: text/html
Server: Development/2.0
Date: Fri, 05 Apr 2013 20:33:08 GMT
Chrome + production server
Initial request headers:
Host: eduzabawy.appspot.com
Connection: keep-alive
Accept-Encoding: identity;q=1, *;q=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31
Accept: */*
Referer: http://eduzabawy.appspot.com/dziecko/
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.3
Cookie: children="sU9aqnqEf67eZFpS7BKSMw\075\075"; session=eyJfc2lkIjoieFlGWlJLMnRwSHJuOVFCb1haTnJLUCJ9|1365194193|2a13cd9eb7aceeb40c43bd82a763d893436d9f1f
Range: bytes=0-
Initial response headers:
HTTP/1.1 206 Partial Content
Cache-Control: public max-age=100000000
ETag: blobstore
Content-Type: audio/mpeg
Content-Range: bytes 0-4636/4637
Date: Fri, 05 Apr 2013 20:36:35 GMT
Server: Google Frontend
Transfer-Encoding: chunked
Subsequent requests and responses are the same as initial.
Your max-age seems too long and going over 3 years... I read from somewhere the maximum you should set in GAE is no more than 1 year.
Anyway, there's one more header you should try to set (Pragma: Public), which worked for me (I'm caching image from blobstore though, here's a few lines from my source code):
httpResponse.Header().Set("Cache-Control", "public, max-age=600")
httpResponse.Header().Set("Pragma", "Public")
blobstore.Send(httpResponse, project.ImageBlobKey)
By the way the above also cause Google to delivery your file from the edge cache, which really speed static resources up a lot!