iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
Modern Web

30天Vue出Google SSO系列 第 19

Day 19. F2E&B2E-登入狀態驗證

https://ithelp.ithome.com.tw/upload/images/20200914/20118686l1xm7ARk9m.jpg

複習一下,第一支API做的登入會將Token以簽章加密的方式存入cookie
而存入之後就可以在需要做登入狀態驗證的頁面上,再次將Token傳到後端來驗證,藉此得到「帳號目前有沒有登入」、「Token還有沒有效」、「帳號是否有權限」等等結果

今天的進度目標要來將登入狀態驗證API開發完成並提供前端呼叫!!
順便複習一下API的實作流程xD


#實作API

開啟我們的後端(b2e)專案開始實作!!

#Step 1

打開 /routes/users/index.js ,新增一個 /checkstatus 路由:

//新增這段~
router.post('/checkstatus', userCtrl.userCtrlCheckStatus);

路徑 checkstatus 對應 controller: userCtrlCheckStatus

#Step 2

打開 /controllers/users.controller.js 加上 controller:

const userCtrlCheckStatus = (req, res) => {    
    userModule.userModuleCheckStatus(req.signedCookies.SigninTokens)
        .then((result) => {
            res.send(Object.assign({ success: true }, result));
        })
        .catch((error) => {
            res.send(Object.assign({ success: false }, error));
        });
};

請求時帶進來的Token傳入module處理:

  • 成功時回傳 success: true 及結果
  • 失敗時回傳 success: false 及錯誤內容

註: req=request(請求),res=response(回覆)

最後記得export:

module.exports = {
    ...,
    userCtrlCheckStatus
}

#Step 3

開啟 /modules/user.module.js 建立對應的module
這裡會先遇到第一個狀況

  • Token是否存在
    • 存在: 曾經有登入過
    • 不存在: 從來沒登入過,直接 reject 「尚未登入」
const userModuleCheckStatus = (signinTokens) => {
    return new Promise((resolve, reject) => {
        if (signinTokens) {
            //dosomething...
        } else {
            reject({ message: "尚未登入" });
        }
    });
};

#Step 4

再來會遇到第二個狀況

  • 啟用中(active) 的Token是否存在
    • 存在: 目前有登入中的帳號
    • 不存在: 目前沒有登入中的帳號,直接 reject 「尚未登入」

(尚未登入真好用xD)

這裡會用到陣列方法 find 來篩選啟用中的Token:

let signinToken = signinTokens.find(function (item) {
    return item.active;
});
if (signinToken) { 
    //dosomething...
} else {
    reject({ message: "尚未登入" });
}

#Step 5

確定Token存在之後,就可以用 jwt的 verify 方法來將 Token和 密鑰 做比對驗證:

jwt.verify(signinToken.token, config.jwt.tokensecret, (error, decoded) => {
    if (error) {
        reject({ message: error });
    } else {
        resolve();
    }
});

verify 會判斷Token是否已經過期(預設30天,超過30天就過期),或是Token是否有被竄改過

  • 有錯誤就 reject 錯誤訊息
  • 成功就 resolve 通過

最後記得export:

module.exports = {
    ...,
    userModuleCheckStatus
};

#結果

API實作結束~
可以用我們神奇的PostMan來測試看看!!
gif已死QQ
一開始沒登入時,請求checkstatus會回覆「尚未登入」
用signin登入之後,再次請求checkstatus則會回覆成功


#串接登入狀態驗證API

前端的驗證流程會是

  • 呼叫API驗證登入狀態
    • 驗證成功: 繼續操作頁面
    • 驗證失敗: 禁止操作頁面,可能導回首頁或是登入等等

這是正常系統做驗證的流程,但這個專案本身就是SSO的母系統了,不需要做驗證,因為就算不登入還是可以用,登入與否對整體操作沒有影響

所以這邊就簡單帶過呼叫API驗證的方式就好~

#Step 1

在我的觀點上會把呼叫登入狀態驗證API的動作放在最外層的 App.vue,用 watch $route 來監聽,當路由變化時就呼叫驗證,根據實際狀況再做微調:

watch: {
  $route: {
    handler: function(to, from) {
      const api = `${process.env.VUE_APP_APIPATH}/users/checkstatus`;
      this.$http({
        method: "POST",
        url: api,
      })
        .then((response) => {
          console.log(response);          
        })
        .catch((error) => {
          console.log(error);
        });
    },
    immediate: true,
  },
},

呼叫API的方式直接大絕招 ctrl+c + ctrl+v 貼過來改一下路由設定就好了xD

  • immediate 之前介紹過,用於在第一次進入頁面就先觸發事件

#Step 2

在呼叫成功時會回覆:

  • success(true/false): 驗證成功或失敗
  • message: 回覆訊息

先用 success 來判斷驗證狀態,如果

  • 驗證成功可以繼續使用頁面
  • 驗證失敗就導回登入或是首頁等等
if (response.data.success) {
  console.log(response.data.message);
} else {
  //this.$router.push({ name: 'somewhere' });
  console.log(response.data.message);
}

如此就完成了前端的登入狀態驗證囉~


今日重點:

  • 複習API製作過程
  • 可用 watch 路由變化來呼叫驗證狀態API

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


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

尚未有邦友留言

立即登入留言