搜尋

首頁  >  問答  >  主體

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就好了。


實在想不到怎麼做了,相關資料也沒找到(可能是我的搜尋方式有問題),所以求各位大佬幫忙....

認真的又查了下這個問題應該是單一登入的問題吧?

淡淡烟草味淡淡烟草味2757 天前1200

全部回覆(1)我來回復

  • 代言

    代言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。

    回覆
    0
  • 取消回覆