iT邦幫忙

0

[ 求教 ] 前端 Token 的儲存流程

  • 分享至 

  • xImage

目前前端 (Angular) 的執行模式是

網站架置同網域,
前端呼叫登入api後得到 JWT TOKEN ,然後將 JWT TOKEN 放置 localstorage,
之後每次呼叫都把 localstorage 的 Token 加入 HTTP hedaers Authorization 字段中,
Refresh Token 則是 呼叫 GetToken 時判斷是否過期,過期則在重新取得 token,
但近期有人告訴我們放置 localstorage 會有安全性的問題,建議我們放置 cookie

請問各位大神,
1.這樣做會有什麼樣的問題?( 我找了許久文章還是不太明白那些地方會有問題,我們該怎麼去修改?)
2.Refresh 的流程是否正確會產生什麼問題嗎? ( 明白沒有什麼正確,不過總應該有常用的做法為基地 )
3.放置 cookie 是否有甚麼實作文章可以參考?Api 是否需要調整?
4.比較通用的 token 流程又是甚麼樣的? ( 抱歉小弟剛轉職,對前端這一塊不是很清楚 )

這是目前前端闡述的流程,以下是程式碼

  GetToken() {
    if(localStorage.getItem("token") == null) {
      this._router.navigate(["回首頁"])
    }else{
      var token =localStorage.getItem("token")
      // 解析 token exp 判斷是否過期 = diff
      if(!diff) this.Refresh()
    }
    return { "Authorization": "bearer " + localStorage.getItem('token') }
  }
  
  
  Refresh(){
    var input = {
      RefreshToken:localStorage.getItem("refresh_token")
    }
   this.api.getRefreshToken(input).then(
    res =>{
      if(res.data.Check){
        localStorage.setItem("token",res.data.access_token!)
        localStorage.setItem("refresh_token",res.data.refresh_token!)
      }else{
        this.createNotification(2,"獲取 Token 失敗")
        this._router.navigate(['回首頁'])
      }
    },
    err =>{
      console.log(err);
      this._router.navigate(['回首頁'])
    }
   )
  }

請各位大神,求教/images/emoticon/emoticon02.gif

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
㊣浩瀚星空㊣
iT邦大神 1 級 ‧ 2023-05-04 18:34:16
最佳解答

其實 Cookie、LocalStorage、SessionStorage 本質上都大同小異。
差別是 cookie 現在有自動加密的處理。(雖然還是可以取出來)
而 LocalStorage 則是直接存實碼。
會覺得安全問題的原因其實是在此。

但就實體安全性而言。認真來說3種都最好不要有重要或隱私的資料存在。
再加上現今 COOKIE 還需要隱私政策的問題。

我個人其實是偏好使用 LocalStorage、SessionStorage。COOKIE沒在用了。
當然了,一些API套件還是會使用到,但那是套件去使用而不是我主動去使用。

一般來說,像是語系相關。記住我等選項設定。會使用LocalStorage。因為本來就不希望讓它過期了。且這些資料就算被修改了也不會有影響。

而登入TOKEN大多數還是會使用 SessionStorage 來儲存。
不過這得看專案用處就是了。

像有需要另開分頁或另開視窗的。存 SessionStorage 就會很不方便。
畢竟 SessionStorage 只會存在當前的分頁上。

不過我大多還是會依 SessionStorage 為主。

一般來說,大多數網路上說明的。是 LocalStorage 是為了儲存購物車的資料為主。
畢竟購物車有時會有很大量的資料存在。使用COOKIE的情況下,常常會因為容量爆掉而網頁失效。
而使用 LocalStorage 則比較不會發生這個問題。(畢竟有5MB的容量)

但就正規而言。這三種你都要將其視為不安全。但不代表不安全就不要使用。
而是要使用它們,要小心存放。重要資料等等則不要存放在內。

回來您的問題來說好了。一般來說存放TOKEN且有時效性的情況下。
使用 LocalStorage 並不會不好。
因為你存放的TOKEN。還是可以用其它方式拿到。
但並不會因為拿到了就會被破解了。

只要你能做到,就算拿到有效的TOKEN到別台電腦或另外的瀏覽器。無法登入。
就算能看到也不會怎麼樣就行了。

至於 Refresh 的做法。
由於我自已的做法是有做一個統一的請求器。
其實每一次的請求回傳。都會檢查有無TOKEN的存在。
而我一般的設定是TOKEN的有效期是 10分。當有效期不滿5分時。就會重新發送新的TOKEN。
而前端接收到新的TOKEN後就會直接更換掉。

抱歉大神,再詢問一下,意思是我無論選擇放在 LocalStorage 或是 COOKIE ,我在發出 api 的時候都必須去取 LocalStorage 或是 COOKIE 內的 token 並把它放在 header Authorization 之中?
還是有法子在我發出 api 的時候自動幫我帶入 header 之中,讓我不必再另外寫方法?

我這邊是用 axios 處理的。
因為 axios 有 request(請求前)及response(請求後)的宣告可以用
所以我是直接將其包成一個請求器處理。
如下的方式來定義所有的請求處理。

import axios from "../plugins/axios";//包好的請求器

/**
 * 登入用
 * @param data
 * @returns {Promise<AxiosResponse<any>>}
 * @constructor
 */
export const LoginApi = (data) => {
  return axios.post(`/login`, data);
};
3
alien663
iT邦研究生 5 級 ‧ 2023-05-04 15:04:58

這邊提供我的見解供你參考

1.這樣做會有什麼樣的問題?( 我找了許久文章還是不太明白那些地方會有問題,我們該怎麼去修改?)

cookie資料是會自動過期的,屆時瀏覽器會自動刪除,但local storage會永久保存,假設使用者很長一段時間沒有登入網站,當然是把資料清除會比較安全。
cookie會自動帶給API,所以前端不用另外做事情處理,整體來說會比較簡易一些,我的API是用.net core寫的,用Filter去處理登入機制,專案在這裡

2.Refresh 的流程是否正確會產生什麼問題嗎? ( 明白沒有什麼正確,不過總應該有常用的做法為基地 )

我是多了一個Refresh Token讓他做回傳,除了Token確認身分外,Refresh Token也要正確才可以換發新的Token

3.放置 cookie 是否有甚麼實作文章可以參考?Api 是否需要調整?

主要是API要調整,前端把local storage存取token的部分拿掉就好,不過這部分應該不難,我不清楚你用的語言,我也無法提供實作文章。

4.比較通用的 token 流程又是甚麼樣的? ( 抱歉小弟剛轉職,對前端這一塊不是很清楚 )

我當初在做的時候,主要參考這個文章,希望會對你有幫助OAuth 2.0 筆記 (1) 世界觀

看更多先前的回應...收起先前的回應...
froce iT邦大師 1 級 ‧ 2023-05-04 20:16:40 檢舉

cookie資料是會自動過期的,屆時瀏覽器會自動刪除,但local storage會永久保存,假設使用者很長一段時間沒有登入網站,當然是把資料清除會比較安全。

這段我是覺得有點問題,token理論上也會過期,而且過期的時間會比cookie短很多,清不清就"存取權"來說我是覺得沒啥太大差別。
但JWT的playload是可以自訂的,而且是公用格式,理論上會放一些不太重要的個人資料,這個如果token被偷就會被看到。

alien663 iT邦研究生 5 級 ‧ 2023-05-05 08:38:40 檢舉

因為他有實作Refresh Token,cookie如果有自動清除會有差別,如果token放在cookie會被偷,那放在local storage也是一樣,因此cookie時間到自動清除是比較安全的。

froce iT邦大師 1 級 ‧ 2023-05-05 10:59:43 檢舉

如果是這樣的考量,那我會建議: token放在cookie或local storage,refresh token放在seesion storage,或乾脆存在狀態管理的變數裡。

而且refresh token我記得一樣會做過期機制,期限也是跟單一token一樣長而已。

alien663 iT邦研究生 5 級 ‧ 2023-05-05 11:39:49 檢舉

這確實是個不錯的做法,我設計自己的side project時在Refresh Token這邊有著實點偷懶了。

我自己的專案是直接把Token跟Refresh Token一起產生,同一筆資料不同欄位去做,然後都丟cookie,用同一個Filter判斷身分和自動換發Token。

確實讓Refresh Token每個Session都不一樣是比較安全的作法,感謝您的建議,受教了。

感謝回答 受益良多~~

/images/emoticon/emoticon41.gif

我要發表回答

立即登入回答