假設我有一個獲取驗證碼的介面它在https://api.b.com/captcha下面。
在我的想像中驗證碼刷新功能是透過在url後面加上?時間戳來實現的,例如把url變成這樣子
https://api.b.com/captcha?149...
傳統的驗證碼應該主要是透過session來做的吧,前端會在cookie裡面記錄一個session id。
後端也會在redis裡面記錄這個session id以及它對應的驗證碼。
前端有個點擊驗證碼刷新的功能,每次點擊都會產生新的驗證碼,每次都會在redis裡面更新這個session id對應的驗證碼的值。
驗證方式是透過查詢redis裡面的session id得值和前端的值是否一致來完成的。
現在,我在做一個前後端分離的專案。
然後有一個cookie跨域的問題我不知道怎麼解決。
場景如下前端項目在 www.a.com的網域下,後端項目在 api.b.com的網域下。
前端和後端是在不同的域名下的(其實把兩個項目放在同一個域名下面也是可以的,學習目的就不這麼做了),於是cookie無法共享,換而言之我獲取不到session id了。那麼傳統的方式好像就不行了。
PS: 前端的伺服器會用nginx做,後端用的是spring-boot。
我想產生一個簡單的token,token只包含了一個uuid,用來辨別使用者。我透過這個toekn的uuid和redis裡面的uuid比對來判斷驗證碼的值是否正確。所以我將會回傳一個這樣子的結果
{
image : base64转码后的图片,
token : uuid
}
關於為什麼發base64轉碼後的圖片,主要是因為前端的img標籤是支援base64的。發這個話直接顯示出來沒問題(不是一個不考慮古老瀏覽器的項目)。
但是這樣子做,好像也不太合理。因為這樣子存取驗證碼的位址的時候就不能看見驗證碼的圖片了。不方便調試查看驗證碼的樣式了,其實也不算特別不方便,只是還要特地寫個js來設定img的src,感覺挺蠢的。
把token放到response的header裡面。 js是唸得到response header裡面的東西的。然後這樣子驗證碼的圖片也可以透過位址直接顯示出來。但是特喵的,感覺也很蠢。因為就不能用到我想像中的刷新驗證碼的方式了。直接簡單的在後面加上時間戳記就修改的方式。
驗證碼我不管了,前端的伺服器去做這事情吧,登陸的時候在前端伺服器驗證驗證碼,然後我後端只驗證帳號密碼是不是正確的回個token算了。每次造訪其他的api帶上token就好了。
實在想不到怎麼做了,相關資料也沒找到(可能是我的搜尋方式有問題),所以求各位大佬幫忙....
認真的又查了下這個問題應該是單一登入的問題吧?
代言2017-06-12 09:22:13
你要解決的是跨域攜帶cookie的問題。首先要確定你跨網域使用的是cors技術,cors可以基於 HTTP cookies 和 HTTP 認證資訊發送身分憑證。 透過XMLHttpRequest 的 withCredentials 標誌設定為 true,從而向伺服器發送 Cookies。
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
function callOtherDomain(){
if(invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true;
invocation.onreadystatechange = handler;
invocation.send();
}
}
除了前端發送請求要新增withCredential外,伺服器的回應頭也需要加入Access-Control-Allow-Credentials: true
。另外,回應頭不能設定 Access-Control-Allow-Origin 的值為“*”,必須設為具體的來源 http://foo.example。