java - 前后端分離驗(yàn)證碼的問題
問題描述
前提假設(shè)我有一個(gè)獲取驗(yàn)證碼的接口它在https://api.b.com/captcha下面。
我想象中的刷新驗(yàn)證碼的方式在我的想象中驗(yàn)證碼刷新功能是通過在url后面加上?時(shí)間戳實(shí)現(xiàn)的,例如把url變成這樣子
https://api.b.com/captcha?149...
傳統(tǒng)驗(yàn)證驗(yàn)證碼的做法傳統(tǒng)的驗(yàn)證碼應(yīng)該主要是通過session來做的吧,前端會(huì)在cookie里面記錄一個(gè)session id。
后端也會(huì)在redis里面記錄這個(gè)session id以及它對(duì)應(yīng)的驗(yàn)證碼。
前端有個(gè)點(diǎn)擊驗(yàn)證碼刷新的功能,每次點(diǎn)擊都會(huì)生成新的驗(yàn)證碼,每次都會(huì)在redis里面更新這個(gè)session id對(duì)應(yīng)的驗(yàn)證碼的值。
驗(yàn)證方式是通過查詢r(jià)edis里面的session id得值和前端的值是否一致來完成的。
目前遇到的問題現(xiàn)在,我在做一個(gè)前后端分離的項(xiàng)目。
然后有一個(gè)cookie跨域的問題我不知道怎么解決。
場(chǎng)景如下前端項(xiàng)目在 www.a.com的域名下,后端項(xiàng)目在 api.b.com的域名下。
前端和后端是在不同的域名下的(其實(shí)把兩個(gè)項(xiàng)目放在同一個(gè)域名下面也是可以的,學(xué)習(xí)目的就不這么做了),于是cookie無法共享,換而言之我獲取不到session id了。那么傳統(tǒng)的方式好像就不可以了。
PS: 前端的服務(wù)器會(huì)用nginx做,后端用的是spring-boot。
我的想法想法一我想生成一個(gè)簡(jiǎn)單的token,token只包含了一個(gè)uuid,用于辨別用戶。我通過這個(gè)toekn的uuid和redis里面的uuid比對(duì)來判斷驗(yàn)證碼的值是否正確。所以我將會(huì)返回一個(gè)這樣子的結(jié)果
{ image : base64轉(zhuǎn)碼后的圖片, token : uuid}
關(guān)于為什么發(fā)base64轉(zhuǎn)碼后的圖片,主要是因?yàn)榍岸说膇mg標(biāo)簽是支持base64的。發(fā)這個(gè)話直接顯示出來沒問題(不是一個(gè)不考慮古老瀏覽器的項(xiàng)目)。
但是這樣子做,好像也并不太合理。因?yàn)檫@樣子訪問驗(yàn)證碼的地址的時(shí)候就不能看見驗(yàn)證碼的圖片了。不方便調(diào)試查看驗(yàn)證碼的樣式了,其實(shí)也不算特別不方便,只是還要特地寫個(gè)js來設(shè)置img的src,感覺挺蠢的。
想法二把token放到response的header里面。js是讀得到response header里面的東西的。然后這樣子驗(yàn)證碼的圖片也可以通過地址直接顯示出來。但是特喵的,感覺也很蠢。因?yàn)榫筒荒苡玫轿蚁胂笾械乃⑿买?yàn)證碼的方式了。直接簡(jiǎn)單的在后面添加時(shí)間戳就修改的方式。
想法三驗(yàn)證碼我不管了,前端的服務(wù)器去做這事情吧,登陸的時(shí)候在前端服務(wù)器驗(yàn)證驗(yàn)證碼,然后我后端只驗(yàn)證賬號(hào)密碼是不是正確的回個(gè)token算了。每次訪問其他的api帶上token就好了。
實(shí)在想不到怎么做了,相關(guān)資料也沒找到(可能是我的搜索方式有問題),所以求各位大佬幫忙....
認(rèn)真的又查了下這個(gè)問題應(yīng)該是單點(diǎn)登錄的問題吧?
問題解答
回答1:你要解決的是跨域攜帶cookie的問題。首先要確定你跨域使用的是cors技術(shù),cors可以基于 HTTP cookies 和 HTTP 認(rèn)證信息發(fā)送身份憑證。 通過XMLHttpRequest 的 withCredentials 標(biāo)志設(shè)置為 true,從而向服務(wù)器發(fā)送 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(); }}
除了前端發(fā)請(qǐng)求要添加withCredential外,服務(wù)器的響應(yīng)頭也需要添加Access-Control-Allow-Credentials: true。另外,響應(yīng)頭不能設(shè)置 Access-Control-Allow-Origin 的值為“*”,必須設(shè)為具體的源 http://foo.example。
相關(guān)文章:
1. docker gitlab 如何git clone?2. docker鏡像push報(bào)錯(cuò)3. docker api 開發(fā)的端口怎么獲取?4. macos - mac下docker如何設(shè)置代理5. debian - docker依賴的aufs-tools源碼哪里可以找到啊?6. dockerfile - 我用docker build的時(shí)候出現(xiàn)下邊問題 麻煩幫我看一下7. docker - 如何修改運(yùn)行中容器的配置8. docker start -a dockername 老是卡住,什么情況?9. angular.js使用$resource服務(wù)把數(shù)據(jù)存入mongodb的問題。10. docker 下面創(chuàng)建的IMAGE 他們的 ID 一樣?這個(gè)是怎么回事????

網(wǎng)公網(wǎng)安備