Set-Cookie not working in browser but works with Postman

Viewed 11304

Frontend is on localhost:4200 and backend is on localhost:8080

I have implemented CORS configurations in my backend and frontend and all the other API requests work. However the Set-Cookie flag is not creating a cookie in my browser.

I have even disabled CORS in chrome.

When I make the POST request using Postman I correctly see the Cookie in the Cookie tabs. I don't see the cookie in the web browser.

OPTION Request

Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.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
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,credentials

OPTION Response

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
Access-Control-Allow-Origin: http://localhost:4200
access-control-allow-credentials: true
access-control-allow-methods: POST, GET, OPTIONS, DELETE
access-control-max-age: 3600
access-control-allow-headers: Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, credentials
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Fri, 30 Jun 2017 14:55:58 GMT

POST Request

Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:4200/login
Content-Type: application/json
credentials: true
Content-Length: 48
Origin: http://localhost:4200
Connection: keep-alive

POST Response

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
Access-Control-Allow-Origin: http://localhost:4200
access-control-allow-credentials: true
access-control-allow-methods: POST, GET, OPTIONS, DELETE
access-control-max-age: 3600
access-control-allow-headers: Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, credentials
Set-Cookie: ddd=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOjJmYXhhcyIsImV4cCI6MTQ5ODkyMDk1OH0.sKJLH1GvgbJP28ws2EOZpc8EH0SElB4VQX86m59G8BjT-QAaRW6sInnrF6Y_yNJcIEcrrw_itb-O26KkKza8aA
Content-Length: 0
Date: Fri, 30 Jun 2017 14:55:58 GMT
5 Answers

What worked for me was similar to @Josueemx but without explicitly setting the additional http methods to the origin area.

All I did was add credentials to the request configuration, an example can be below

const config = {
headers: {
  "Content-Type": "application/json"
  },
  withCredentials: true
}

then added that to the axios.post('host',SomeDataHere, config)

then setting the exact origin with credentials to cors like MrMisery suggested. An example can be.

app.use(cors({
    origin: 'http://localhost:3000',
    credentials: true,
}));

What worked for me was MrMisery's answer, but I also added all available methods (using Spring Boot):

@RestController
@CrossOrigin(
        //origins = "*", aqui dejar este si la hace de pedo
        origins = {"http://localhost:3000"},
        allowCredentials = "true",
        maxAge = 3600, 
        allowedHeaders = "*",
        methods= {RequestMethod.GET,RequestMethod.POST, 
                RequestMethod.DELETE, RequestMethod.PUT, 
                RequestMethod.PATCH, RequestMethod.OPTIONS, 
                RequestMethod.HEAD, RequestMethod.TRACE}
)
@RequestMapping("/access")
public class AccessController {...

of course on my login endpoint I set the cookie:

...
//set cookie on response
Cookie authCookie = new Cookie(COOKIE_NAME, jwt);
authCookie.setHttpOnly(true);
authCookie.setMaxAge(JWT_EXPIRATION_TIME * 60 * 60);//3 hours
authCookie.setVersion(0);
authCookie.setPath("/");
response.addCookie(authCookie);
//return response
return ResponseEntity.ok(new ResponseLoad(
    Message.TYPE_MESSAGE,
    Message.SEVERITY_SUCC,
    null,
    therapist));

and finally use withCredentials in Axios in my React client like so:

const config = {
        headers: {
            "Content-Type": "application/json"
        },
        withCredentials: true
    };

    await axios
        .post(apiURL + apiVersion + "/access/login", { email, password }, config)
        .then((response) => {

            sessionStorage.setItem(
                "somedata" + storageCode,
                JSON.stringify(response.data.subBody)
            );

            dispatch({
                type: THERAPIST_LOGIN_SUCCESS,
                payload: response.data.subBody
            });
        })

I wasn't able to see the cookie on the response headers but once I checked (using Chrome) dev tools > Application > Storage section - Cookies and clicked on http://localhost:3000 THERE IT WAS!!!

I was experiencing the exact same issue where the cookie was saving on postman but not the browser.

The problem started occurring for me after I deployed my frontend (React) and backend (Django REST API) to different servers, both using secure https connections.

The solution for me was to set the cookie attributes samesite='None' and secure=True.

Related