java - 前后端分離驗證碼的問題
問題描述
前提假設我有一個獲取驗證碼的接口它在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就好了。
實在想不到怎么做了,相關資料也沒找到(可能是我的搜索方式有問題),所以求各位大佬幫忙....
認真的又查了下這個問題應該是單點登錄的問題吧?
問題解答
回答1:你要解決的是跨域攜帶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。
相關文章:
1. javascript - vue 移動端的input 數字輸入優化2. java - mongodb分片集群下,count和聚合統計問題3. java - 自己制作一個視頻播放器,遇到問題,用的是內置surfaceview類,具體看代碼!4. android - java 泛型不支持數組,那么RxJava的Map集合有什么方便的手段可以定義獲得一串共同父類集合數據呢?5. 服務器端 - 采用nginx做web服務器,C++開發應用程序 出現拒絕連接請求?6. 為什么我ping不通我的docker容器呢???7. 關于docker下的nginx壓力測試8. python - pandas按照列A和列B分組,將列C求平均數,怎樣才能生成一個列A,B,C的dataframe9. javascript - 有什么兼容性比較好的辦法來判斷瀏覽器窗口的類型?10. java - 靜態屬性中的賦值和靜態代碼塊中的賦值有什么區別?
