saito.k 4ce2bbf823 Merged PR 5: タスク 1471: 画面実装(トークン系)
## 概要
[Task: 1471](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_sprints/taskboard/OMDSDictation%20%E3%83%81%E3%83%BC%E3%83%A0/OMDSDictation/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%203-2?workitem=1471)

- アクセストークンの自動更新処理を実装
  - UpdateTokenTimerで定期実行を行う
- 未ログインまたはトークンが期限切れの状態で、ログイン後の画面にアクセスした場合、Topページにリダイレクトする処理を実装
  - RouteAuthGuard.tsx
- APIからのレスポンスが401だった時にTopページにリダイレクトする処理を実装
  - App.tsx

## レビューポイント
- 今の実装だとトークンの自動更新に失敗した場合、画面上では何も起こらないようにになっている
  - 更新が失敗し続け、アクセストークンが切れた段階でRouteAuthGuardではじかれてTopへリダイレクトする
- トークンの期限を確認する間隔を3分にしているが問題なさそうか

## UIの変更
-

## 動作確認状況
- ローカルで動作確認

## 補足
2023-03-08 00:57:55 +00:00

39 lines
1.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useCallback } from "react";
import { AppDispatch } from "app/store";
import { decodeToken } from "common/decodeToken";
import { useInterval } from "common/useInterval";
import { updateTokenAsync } from "features/auth/operations";
import { loadAccessToken } from "features/auth/utils";
import { DateTime } from "luxon";
import { useDispatch } from "react-redux";
//アクセストークンを更新する基準の秒数
const TOKEN_UPDATE_TIME = 5 * 60;
//アクセストークンの更新チェックを行う間隔(ミリ秒)
const TOKEN_UPDATE_INTERVAL_MS = 3 * 60 * 1000;
export const UpdateTokenTimer = () => {
const dispatch: AppDispatch = useDispatch();
// 期限が分以内であれば更新APIを呼ぶ
const updateToken = useCallback(async () => {
// localStorageからトークンを取得
const jwt = loadAccessToken();
// selectorに以下の判定処理を移したかったが、初期表示時の値でしか判定できないのでComponent内に置く
if (jwt) {
const token = decodeToken(jwt);
if (token) {
const { exp } = token;
const now = DateTime.local().toSeconds();
if (exp - now <= TOKEN_UPDATE_TIME) {
await dispatch(updateTokenAsync());
}
}
}
}, [dispatch]);
useInterval(updateToken, TOKEN_UPDATE_INTERVAL_MS);
// eslint-disable-next-line react/jsx-no-useless-fragment
return <></>;
};