上次在項目中作一個手機驗證碼功能時遇到後端set-cookie
沒法成功的問題,相信不少人都會遇到,今天分享出來,算是作個記錄,也給有須要的小夥伴一個參考,下面先說一下場景前端
用戶輸入手機號並點擊發送驗證碼按鈕express
此時是向後端服務器發起高請求,傳遞手機號碼
後端接收到手機號碼後經過短信服務商的接口發送短信到手機號後端
因爲安全性問題,通常服務商的接口都是由後端發起請求,那驗證碼是怎麼來的呢?固然是咱們本身後端生成的(通常是生產一個4位或6位隨機數字號碼),短信接口只負責發送
問題來了,咱們都知道http請求是無狀態的,即每一個請求都是獨立的,兩個請求間沒有任何聯繫,但上面的步驟中,用戶發起了兩次請求(第1步和第3步),後端怎麼知道是同一我的呢?萬一當時有10我的同時獲取驗證碼,且都執行完全部步驟,怎麼實現各自第1和第3步的對應關係進而進行第4步校驗?因而咱們引入session
跨域
session
是保存的服務器的一個數據存儲機制,通常用於存儲用戶狀態數據,你能夠理解爲客戶端的cookie
,由於它們很像,一樣是有key/value
和有效時間,只是一個在服務端,一個在客戶端。這跟本文有什麼關係呢?確定有關係,關係大了去了,否則我寫幹嗎(自嗨中~~~)瀏覽器
咳~咳。。迴歸正題,剛剛說了http是無狀態的,而咱們如今又要把第1步和第3步關聯起來,怎麼關聯呢?session+cookie出馬,具體原理以下安全
第一次接到請求,後關會生成一個sessionid
來標識當前會話(我使用express-session
來實現),並經過set-cookie
響應頭在客戶端生一個cookie,大概長這樣,服務器
connect.sid=s%3Au9xG34DBU1vOVbIpCax0neMxL_Uc1fIC.4ndNJL5G%2B41DtUSLbQ%2BW75Z9wduOAON4lfu2JGTDe5
sessionid
給服務器,服務器經過這個sessionid
來標識是否爲同一個用戶,問題就迎刃而解了...前端:cookie
後端:session
session
,並給前端響應connect.sid
(express-session會Set-Cookie
響應頭)前端:併發
Set-Cookie
響應頭後,自動把sessionid
寫入瀏覽器cookie
sessionid
隨cookie
自動發送到後端)後端:
session
的隨機驗證碼進行比較,一致則響應成功,不然響應失敗經過以上步驟,正常狀況下你已經能實現手機驗證碼功能了,可我恰恰遇到了非正常狀況,這也是我今天這篇文章的意義,因爲開發階段爲先後端分享,請求是產生了跨域,明明已經正確響應了Set-Cookie
,容許了CORS
跨域,但瀏覽器的cookie中就是看不到connect.sid
的身影,關鍵瀏覽器還不報錯。
因而各類千里尋她千百度,最後發現Set-Cookie
在跨域時默認是被瀏覽器忽略的,解決的方案是兩步:
"Access-Control-Allow-Credentials":true
響應頭withCredentials:true
請求頭搞定,收工,但願對你有幫助