iT邦幫忙

2

Chrome 不處理 Set-Cookie header

-以下情況都在dev環境中-

小弟最近剛接觸web,爬了好多文章看到好像cookie的policy最近有改的樣子,不知道是不是套件沒有支援到或是什麼的...自己蝦g8弄了好久還是沒有成功希望大神可以救救小弟QwQ

情境:

使用者Login後即在cookie中設定一組token.

前端: react-create-app
後端: express
Chrome版本: 80+

登入的res&req

ResponsHeader

Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 200
Content-Type: application/json; charset=utf-8
Date: Fri, 17 Apr 2020 06:49:53 GMT
ETag: W/"c8-yxhJ5QXo1kTXdhXSWstzpOrrfE4"

Set-Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJpbGx5IiwiZW1haWwiOiJiaWxseUBnbWFpbC5jb20iLCJpYXQiOjE1ODcxMDYxOTMsImV4cCI6MTU4NzcwNjE5M30.l4BzNCsJ6Kox5UfP8xkdx4DuUGSb5Cw58v_hAbEywRY; Max-Age=600; Path=/; Expires=Fri, 17 Apr 2020 06:59:53 GMT; HttpOnly

X-Powered-By: Express

Request Header

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 38
Content-Type: application/json
Host: localhost:3001
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36

本應該帶著cookie的fetch

      fetch(`http://localhost:3001/users/${this.props.CurrentUser}`, {
            credentials: 'same-origin',
            method: 'GET',

        })
        .then((Response) => {
            if(Response.ok) {
                Response.json()
                .then(data => {
                    this.setState({dirArray: data});
                })
            }
        })

-> server回傳錯誤訊息(沒有設定cookie(token))

2 個回答

1
dragonH
iT邦超人 6 級 ‧ 2020-04-17 15:11:03
最佳解答

不知道這有幫助嗎

fetch

看更多先前的回應...收起先前的回應...
jokie7585 iT邦新手 5 級 ‧ 2020-04-17 15:13:26 檢舉

有...非常之有..
看來我下次應該到github去找資料而不是MDN了..

jokie7585 iT邦新手 5 級 ‧ 2020-04-17 15:28:26 檢舉

啊...我發現我看太快了看錯了 我只知道Set-Cookie是被禁止的
但我不是很確定這句話的意思
'it's the browser's responsibility to handle new cookies being set (if applicable to the current URL)'

通靈亡 iT邦研究生 5 級 ‧ 2020-04-17 15:30:46 檢舉

這句話就是在講Cors

dragonH iT邦超人 6 級 ‧ 2020-04-17 15:46:35 檢舉

/images/emoticon/emoticon42.gif

dragonH iT邦超人 6 級 ‧ 2020-04-17 15:49:40 檢舉

其實 MDN 上面也有說阿

fetch 和 jQuery.ajax() 有兩個主要的差異:
fetch() 回傳的 promise 物件, resolve 和 reject 的使用方式有差異, 當遇到 HTTP Status 404, 500 時會使用 resolve 但會將 status 的值從 ok 變為 false, reject 只有在網路發生錯誤或是任何會中斷網路請求時才會使用。
fetch 預設上不傳送或接收任何 cookies,如果網站依賴 session 會導致請求回傳未經認證,需要使用 cookies 必須額外設定 credentials。

jokie7585 iT邦新手 5 級 ‧ 2020-04-17 16:06:10 檢舉

原來會造成set-cookies的responseheader的request也要credentials!
但我現在遇到了一個新的問題我貼在下面大大的回答裡面了,現在我是用postman做都ok,但一移動到chrome上就爆炸QwQ
想說是不是postman做了什麼我沒注意到的事情?

0
通靈亡
iT邦研究生 5 級 ‧ 2020-04-17 15:22:28
Host: localhost:3001
Origin: http://localhost:3000

該不會是CORS的問題?
如果是的話,credentials: "same-origin" 改成 credentials: 'include'

看更多先前的回應...收起先前的回應...
jokie7585 iT邦新手 5 級 ‧ 2020-04-17 15:30:42 檢舉

好像不是呢..他有response正確的失敗訊息回來
最直觀的是login之後他並沒有設定cookie

通靈亡 iT邦研究生 5 級 ‧ 2020-04-17 15:32:32 檢舉

https://github.com/github/fetch/issues/386

So, I have two requests; one login request and one customer request. It is the login request that gets the set-cookie header in its response, and then the user should be loggen in.

There is an option called credentials: 'same-origin', which I did not send with the login request (because I thought it only needed to be sent with requests after I was logged in.)

jokie7585 iT邦新手 5 級 ‧ 2020-04-17 15:38:18 檢舉

謝謝您~我先研究一下QwQ

jokie7585 iT邦新手 5 級 ‧ 2020-04-17 16:04:04 檢舉

我按照他說的把我的loginRequest改成這樣

fetch('http://localhost:3001/api/auth/login', {
  credentials: 'include',
  method: 'POST',
  headers:{
     'Content-Type' : 'application/json'
  },
  body: JSON.stringify(payload)
})
.then(....)
但變成console出現此錯誤訊息
Access to fetch at 'http://localhost:3001/api/auth/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

但我用postman發option測試的時候Access-Control-Allow-Origin的值確實是'*', 在postman上測試相同的API組合結果也都正確,結果換到chrome上就不能正常運作了.
我在想是不是postman幫我做了什麼我沒注意到的事情.

通靈亡 iT邦研究生 5 級 ‧ 2020-04-17 16:15:08 檢舉

如果Request 要傳送 Cookie 到後端
除了在 前端 Request 要設定credentials
後端 Express 的 Access-Control-Allow-Origin 不可以為'*'

要設定成一個指定域名(前端的ip或域名),例如:

Access-Control-Allow-Origin:"http://localhost:3000"

https://enable-cors.org/server_expressjs.html
https://note.pcwu.net/2017/03/16/nodejs-cors/

jokie7585 iT邦新手 5 級 ‧ 2020-04-17 16:56:12 檢舉

原來是不可以為'*'...ㄋ
我整個人都被搞傻了QWQ
感謝大大啊啊啊啊

我要發表回答

立即登入回答