iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
Modern Web

30天Vue出Google SSO系列 第 17

Day 17. B2E-加入Token

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20200907/20118686ReGoyDPOPu.jpg

學會了前端對後端的API串接,並且實作了登入的動作
雖然很開心,但是就只有登入而已!!
換句話說,就是後端只告訴你「哦~你的帳號密碼是對的,好蚌蚌喔,讓你登入吧~」,就結束了!!
沒有做其他任何紀錄登入狀態的動作
所以就算登入成功了,也無從判斷登入狀態

今天的目標進度就是要在登入時加入Token,利用 Token 來協助判斷帳號的登入狀態!!


#Token是什麼?

當你去遊樂園玩,進場前會需要先買票,進場後玩一玩突然發現手機忘在車上沒帶,所以又出場去拿手機,這時候再進場,只要拿剛才買的票的票根就可以進去,不需要再重新買票

Token 就是這張票卷,只要登入一次就會把票卷給你讓你記錄下來,下次再開啟頁面帶上票卷檢查通過就不用再登入!!


#實作加入Token

接著就來實作登入時加入Token吧!!
一個帳號會對應一組token,使用瀏覽器的cookie來記錄它,因為帳號不只一個,所以cookie有可能會有紀錄多組token的情況

Token的部份使用JWT(JSON Web Token),JWT可以利用設定的密鑰對Token內容做編碼加密的動作

註: Token內容只要解密就可以看見,所以不要把敏感資訊放進去

#Step 1

首先開啟後端專案,來安裝 JWT 套件:

npm install jsonwebtoken

裝好之後開啟 /modules/users.module.js 引用它:

const jwt = require('jsonwebtoken');

#Step 2

接著我們在登入成功的resolve之前,來組合出需要的Token內容:

const payload = {
    accountId: user.accountId,
    username: user.username,
    exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30
};
  • accountId: 帳號
  • username: 姓名
  • exp: token有效期,這邊設定30天

組合之後來和 密鑰 一起簽章:

const token = jwt.sign(payload, 'THISISMYTOKENSECRET');

把簽好的 Token 加入回傳:

resolve({ message: '登入成功', token });

Token的部份就準備完成囉!!

註: 密鑰和有效期可以設定在config

#Step 3

接著規劃將Token存入cookie中,cookie存放的會是一個陣列組合像這樣:

[
    //第一個token
    {
        token: 'aaa.bbb.ccc',
        active: true
    },
    //第二個token
    {
        token: 'ddd.eee.fff',
        active: false
    },
]
  • token: 登入票卷
  • active: 啟用狀態

在帳號登出之後,系統還是會記錄它的帳號資訊,以便下次快速登入使用,登出後的帳號就會是「未啟用」狀態
簡單的判斷方式: 登入中的帳號為 true,其他都是 false

#Step 4

了解格式內容之後,開啟 /controllers/users.controller.js,建立一個陣列:

let signinTokens = [];

把Token及啟用狀態塞進去:

signinTokens.push({ token: moduleResult.token, active: true });

最後陣列存入cookie中:

res.cookie('SigninTokens', signinTokens);

#Step 5

做到這邊會發現cookie怎麼存就是存不進去xD
檢查了一下發現原來是之前就忘了把開關打開/images/emoticon/emoticon01.gif

所謂的開關就是 withCredentials 這個設定,開啟之後就可以在請求時帶入cookie

注意!!在前端與後端專案都需要加入唷!!

前端的部分,開啟專案中的 main.js 加入這行:

axios.defaults.withCredentials = true;

後端的部分,開啟專案中的 app.js,在 cors 的屬性設定中加上:

app.use(cors({
  credentials: true,
  ...
}))

#結果

加好之後再重新登入一次,登入後到Chrome的開發人員模式就可以找到剛才存入的cookie囉~
https://ithelp.ithome.com.tw/upload/images/20200907/20118686TuMjWEMPc9.jpg


#JWT線上解析

分享一個 JWT 線上解析的網頁 - JWT
如果把剛才做的Token放進去解析會長這樣:
https://ithelp.ithome.com.tw/upload/images/20200907/20118686fpYPl1QTh1.jpg

可以看到它馬上把你的payload內容解析出來,所以說不要把敏感資料放在這邊~
而密鑰它是解析不出來的
所以之後也會需要用到密鑰來判斷Token的真實性

用什麼密碼鎖住,就要用什麼密碼解開,像極了愛情


今日重點:

  • Token 就像遊樂園票卷,買了之後可以無限進出
  • 前後端都須開啟 withCredentials 設定,發送請求時才會帶上cookie值
  • 敏感資料不要放在Token裡面

今天完成了使用 cookie 儲存 Token啟用狀態,但是有個嚴重的Bug,我只要登入一次,它就push一筆資料進去,登入一百次就push一百筆,而且每一筆都是 啟用中 ,像極了愛情xD

這個邏輯Bug先讓它飛一會兒吧~

有需要改進或是任何意見建議歡迎下面留言~


上一篇
Day 16. F2E-Axios呼叫API
下一篇
Day 18. B2E-Token邏輯修改
系列文
30天Vue出Google SSO30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言