[whatwg/fetch] CORB blocking JSON response after redirect (#854)

Hey, so I've run into a snag with CORB and how it's handling my fetch POST request.  I've done some reading on CORB and noticed there's been a lot of discussion here on the topic, so I was hoping someone could explain why this is happening.

I've got a React site I'm developing locally running on port 3000 and a Kotlin/Spring backend I've got running on port 8080.  I'm making a fetch POST request to `http://localhost:8080/oauth/authorize` with an Authorization header and the required params encoded as form data (client_id, response_type, redirect_uri, and scope).  Upon making the request, my server issues a 302 redirect to `http://localhost:8080/redirect?code=abcd1234`, where I then make a request to my token endpoint `http://localhost:8080/oauth/token` with the required params (client_id, client_secret, code, grant_type, and redirect_uri).  When a token is obtained, it returns the token as JSON with a content type of application/json, which is then blocked by CORB on the browser side.

I feel like, from everything I've read so far, that a valid JSON response with an accurate content-type header should not be blocked in this manner.  I don't think it's my redirect that's causing the issue and if it is I don't understand why.

Here are some examples of the requests I've explained:

Example Postman request
```
POST http://localhost:8080/oauth/authorize


HEADERS:
Authorization:Basic Ynppb2xrbzphc2Rm

FORM DATA:
client_id:client-id
response_type:code
redirect_uri:http://localhost:8080/redirect

scope:read

RESPONSE:
{
    "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDYxMDA5NjgsInVzZXJfbmFtZSI6ImJ6aW9sa28iLCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJqdGkiOiJhNWZlZmJhOC01Yjg4LTQ2ZTUtOTdkNy1mNDJhOTc2ZjAzYTgiLCJjbGllbnRfaWQiOiJyaWRlLXdlYiIsInNjb3BlIjpbInJlYWQiXX0.bUeZKfazDToGUGqBl6JlzHy1iwsUhEzjErkCdHYfA-U",
    "expiration": "Dec 29, 2018 10:29:28 AM",
    "tokenType": "bearer",
    "refreshToken": {
        "expiration": "Jan 28, 2019 7:29:28 AM",
        "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJiemlvbGtvIiwic2NvcGUiOlsicmVhZCJdLCJhdGkiOiJhNWZlZmJhOC01Yjg4LTQ2ZTUtOTdkNy1mNDJhOTc2ZjAzYTgiLCJleHAiOjE1NDg2ODIxNjgsImF1dGhvcml0aWVzIjpbIkFETUlOIl0sImp0aSI6IjQ3YWNlYTFlLWNkNzItNDMzMi1iNTUyLTVlMmFkOTcxOGIzYyIsImNsaWVudF9pZCI6InJpZGUtd2ViIn0.bqE-qALuDXjIoEbnhz9AQZnoNmXPjwtE3AFPKmeIdU4"
    },
    "scope": [
        "read"
    ],
    "additionalInformation": {
        "jti": "a5fefba8-5b88-46e5-97d7-f42a976f03a8"
    }
}

RESPONSE HEADERS:
X-Content-Type-Options →nosniff
X-XSS-Protection →1; mode=block
Cache-Control →no-cache, no-store, max-age=0, must-revalidate
Pragma →no-cache
Expires →0
X-Frame-Options →DENY
Content-Type →application/json;charset=UTF-8
Transfer-Encoding →chunked
Date →Sat, 29 Dec 2018 13:29:28 GMT
```

Example fetch() request (taken from Chrome's network tab)
```
Request URL: http://localhost:8080/oauth/authorize

Request Method: POST
Status Code: 302 
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade 

HEADERS:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Basic Ynppb2xrbzphc2Rm
Connection: keep-alive
Content-Length: 477
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary6WibTt1lQzGl31fP
Cookie: JSESSIONID=871BDFB4758340C9CE814451A656F3BA
Host: localhost:8080
Origin: http://localhost:3000

Referer: http://localhost:3000/login

Sec-Metadata: destination="", site=same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36

FORM DATA:
client_id: client-id
response_type: code
redirect_uri: http://localhost:8080/redirect

scope: read

RESPONSE:
<empty>

RESPONSE HEADERS:
Cache-Control: no-store
Content-Language: en-US
Content-Length: 0
Date: Sat, 29 Dec 2018 13:23:55 GMT
Location: http://localhost:8080/redirect?code=NkMU7B

Set-Cookie: JSESSIONID=C403BCD7F46766B3992C165B69097757; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
```

Then there's the subsequent redirect request:
```
Request URL: http://localhost:8080/redirect?code=NkMU7B

Request Method: GET
Status Code: 200 
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade

HEADERS:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cookie: JSESSIONID=C403BCD7F46766B3992C165B69097757
Host: localhost:8080
Referer: http://localhost:3000/login

Sec-Metadata: destination="", site=same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36

RESPONSE:
<empty>

RESPONSE HEADERS:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Sat, 29 Dec 2018 13:24:40 GMT
Expires: 0
Pragma: no-cache
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
```

I can see that my server properly prepared a response identical to the postman response (with token/dates/times changed obviously), but then CORB removes the entire JSON payload from the redirect response and throws up the Chrome warning.

This is the fetch() request I'm making, though I've tweaked the settings a bunch while trying to play around with this:

```
        fetch(postUrl, {
            method: "POST",
            credentials: "include",
            redirect: "follow",
            mode: "no-cors",
            cache: "no-store",
            headers: head,
            body: formData
        })
            .then((response) => {
                if (!response.ok) {
                    throw Error(response.statusText);
                }

                dispatch(postLoading(false));
                return response;
            })
            .then((response) => response.json())
            .then((response) => dispatch(postSuccess(response)))
            .catch(() => dispatch(postError(true)));
```
And you can just picture that the url, headers, and form data are as described above.

Any thoughts on this?  I'm new to this CORB stuff but there's so little info out there right now given how fresh this is.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/issues/854

Received on Saturday, 29 December 2018 13:51:36 UTC