Vueユーザーが長時間操作せずにログインページからログアウトするように実装する2つの方法

Vueユーザーが長時間操作せずにログインページからログアウトするように実装する2つの方法

問題の説明

この製品では、セキュリティ上の理由から、ユーザーが長時間何も操作を行わない場合、銀行アプリと同様にログインページに戻され、再度ログインするよう求められるとしている。この記事では、この効果を実現する 2 つの方法、つまりフロントエンド制御とバックエンド制御について説明します。それぞれの詳細と適用可能な使用シナリオが異なります。

フロントエンド制御(方法1)

アイデア

まず、ユーザーが長期間操作を行わない具体的な兆候は何でしょうか?実際には、イベントが長い間トリガーされていないかどうかです。

たとえば、ユーザーが長時間操作していない場合、マウスのクリック イベント、マウス ホイール イベント、マウスの移動イベントなどは発生しません。これらのイベントを監視するだけで済みます。これらのイベントが長時間トリガーされない場合は、ユーザーが長時間操作していないことを意味し、ルートはログイン ページにジャンプできます。

これら 3 つのイベントのうち、より実用的なマウス クリック イベントを選択しました。一般的に、プロジェクトの最初のページはログイン ページであるため、ユーザーがログイン ページでログイン ボタンをクリックすると、ログイン ボタンをクリックした時間が記録され、セッション ストレージに保存されます。メイン ページにジャンプすると、ユーザーがページをクリックするたびに、セッション ストレージに保存されている時間が更新されます。同時に、ループ タイマーがページにバインドされます。一定間隔で、現在の時間と、セッション ストレージに保存されている最後のクリック イベントの時間を比較します。差が一定時間を超えると、ユーザーはログイン ページに強制的に移動されます。

コード

login.vue ページ

//html
<el-button type="primary" @click="loginIn">クリックしてログイン</el-button>

// js
メソッド: {
    ログイン() {
      // 最初のクリックの時間を保存します sessionStorage.setItem("lastClickTime", new Date().getTime());
      //バックエンドをシミュレートしてトークンを返す
      sessionStorage.setItem('トークン'、"トークン")
      this.$router.push({
        パス: "/"、
      });
    },
}

Home.vue ページ

<テンプレート>
  <div class="homeBox">
    <!-- 左側はメニュー レベルです -->
    <div class="left">
      <div class="leftNav">
        <el-メニュー
          :default-active="アクティブインデックス"
          クラス="elMenu"
          背景色="#333"
          テキストカラー="#B0B0B2"
          アクティブテキストカラー="#fff"
          :unique-opened="true"
          ルーター
          ref="elメニュー"
        >
          <el-menu-item index="/vue">
            <i class="el-icon-location-outline"></i>
            <span slot="title">vue ページ</span>
          </el-menu-item>
          <el-menu-item index="/react">
            <i class="el-icon-star-off"></i>
            <span slot="title">React ページ</span>
          </el-menu-item>
          <el-menu-item index="/angular">
            <i class="el-icon-pear"></i>
            <span slot="title">角度ページ</span>
          </el-menu-item>
        </el-menu>
      </div>
    </div>
    <!-- 右側はビュー階層です -->
    <div class="right">
      <div class="rightTop">
        <el-button type="primary" plain @click="loginOut">ログアウト</el-button>
      </div>
      <div class="rightBottom">
        <ルータービュー></ルータービュー>
      </div>
    </div>
  </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: "ホーム",
  データ() {
    戻る {
      アクティブインデックス: this.$route.path,
      タイマー: null、
    };
  },
  作成された() {
    /* 
      最初のステップ:
        コンポーネントが初期化され、ロードされると、クリック イベントをリッスンするようにバインドされます。注: addEventListener の 3 番目のパラメータをここで追加する必要があります。
        3 番目のパラメータは、バブリングかキャプチャリングかを決定します (バブリングの場合は false、キャプチャリングの場合は true がデフォルト)。クリック イベントをリッスンするようにバインドしているため、トップレベルの DOM 位置でクリック イベントをキャプチャします。そのため、3 番目のパラメータ true を追加して、内部レイヤーの任意の場所でクリック イベントをリッスンし、クリック時間を保存できるようにする必要があります。*/
    ウィンドウにイベントリスナーを追加します(
      "クリック"、
      () => {
        // 便宜上、クリック イベントの時刻を sessionStorage に直接保存し、簡単に取得して比較できるようにします。sessionStorage.setItem("lastClickTime", new Date().getTime());
      },
      真実
    );
  },
  マウント() {
    /*
      ステップ2:
        コンポーネントが初期化されロードされると、タイマーをバインドして、タイマーの定期的なポーリングを通じて現在の時刻と最後のクリック時刻の差を比較する必要があります*/
    これはタイムアウトです。
  },
  メソッド: {
    タイムアウト() {
      // タイマーを使用する前に、タイマーをクリアします。clearInterval(this.timer);
      this.timer = setInterval(() => {
        let lastClickTime = sessionStorage.getItem("lastClickTime") * 1; // 最後のクリックの文字列時間をデジタル時間に変換します。let nowTime = new Date().getTime(); // 現在の時刻を取得します。console.log("現在の時刻と前回のクリック時刻", nowTime, lastClickTime);
        // 要件は次の通りとします: 5秒間クリックが行われなかった場合、ログインとログアウトのプロンプトが表示されます if (nowTime - lastClickTime > 1000 * 5) {
          // ユーザーにこれを表示します。$message({ type: "warning", message: "タイムアウト、ログアウトしました" });
          // ここでタイマーをクリアしてタスクを終了する必要があります clearInterval(this.timer);
          //最後にログインページに戻ります this.$router.push({ path: "/login" });
        }
      }, 1000);
    },
  },
  破棄する前に() {
    // 最後のステップは、タイマーをクリアし、ページを離れるときにクリック イベント clearInterval(this.timer) をバインド解除することです。
    window.removeEventListener("click", () => {}, true);
  },
};
</スクリプト>

ここで階層的な対応に注意してください。私のプロジェクトの階層関係は、Home.vue ページが App.vue ページの内側のレイヤーであり、対応するビューもあり、ビューがページ全体の関係に対応しています。ルーティング テーブルの階層とルーター ビューの関係に応じて、適切な階層を選択し、対応するクリック イベントとタイマーをバインドします。

つまり、階層関係は、login.vueレベルと並行して次のレベルを選択することです。そうしないと、タイマーとクリックバインディングイベントもlogin.vueページで実行されます。

レンダリング

バックエンド制御(方法2)

アイデア

このバックエンド制御方法は、フロントエンド制御ほど制限的ではありませんが、使用することもできます。
ユーザーが長時間操作を行わない場合、リクエストを送信しないことがわかっています。バックエンドと次のように合意しました。
ユーザーの現在のリクエストと最後のリクエストの間隔が、30 分以上など、一定の時間を超えた場合。すると、バックエンドから返されるステータス コードは 200 ではなく、4567 などの特別なステータス コードになります。次に、フロントエンドの応答インターセプターで判断を追加できます。ステータス コードが 4567 の場合、リクエストがタイムアウトしたことを意味し、ユーザーが長時間操作していないことを示します。このとき、ルートはログイン ページに直接ジャンプできます。

バックエンドはJWTメカニズムを使用して返されるステータスコードを制御します。

コード

ここでは、main.jsのVueのインスタンスオブジェクトをグローバルオブジェクトwindowにマウントし、レスポンスインターセプターのvmオブジェクトでルーティングジャンプメソッドを使用できるようにします。

main.js ファイル

// ウィンドウオブジェクトにマウント window.vm = new Vue({
    店、
    ルーター、
    レンダリング: h => h(App),
}).$mount('#app')

レスポンスインターセプターファイル

http.interceptors.response.use((res) => {
    console.log('グローバルに登録',vm);
    var コード = res.data.code;
    if(code == 4567){ // 4567 はタイムアウト ステータス コードです。この記号が表示されたら、ユーザーにログアウトを求めます。 // この時点でルート ジャンプは this.$router.push() ではないことに注意してください。 vm._router.push({ path: "/login" });
    }
    res.dataを返す
}, (エラー) => {
    // コンソール.log(エラー)
    Promise.reject(error) を返します。
})

VMインスタンスオブジェクトを印刷する

したがって、レスポンスインターセプターのルートジャンプは vm._router.push({ path: "/login" }) になります。

要約する

上記の2つの方法を使用できます。どちらの方法を使用するかは状況によって異なります。

以上で、Vueユーザーが長時間操作しない場合のログインページへのログアウト方法についての2つの説明は終了です。Vueユーザーが長時間操作しない場合のログアウトに関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vueは長時間操作していないユーザー向けに自動ログイン・ログアウト機能を実装
  • Vueでは、jsはインターフェースが長時間操作されない場合に自動的にログアウトされることを決定します(推奨)

<<:  MySQL における一般的なランキングの問題をいくつかまとめます

>>:  Linux で xargs コマンドを使用する詳細なチュートリアル

推薦する

JavaScript タイマー原理の詳細な説明

目次1. setTimeout() タイマー2. setTimeout() タイマーを停止する3. ...

泡の小さな鋭角効果を実現するCSS

効果画像(境界線の色が薄すぎるので、{} で囲みます): { }参考リンク Pure CSS バブル...

リソースアップロード機能を実現するための SpringBoot+nginx の詳細な例

最近、画像、ビデオ、CSS/JS などの静的リソースを配置するために nginx を使用する方法を学...

Docker Compose のインストールと使用手順

目次1. Docker Compose とは何ですか? 2. Docker Composeのインスト...

MySQL でスロークエリログ機能を有効にする方法

MySQL スロー クエリ ログは、問題のあるクエリを追跡するのに非常に役立ちます。現在のプログラム...

Vue の基本リスナーの詳細な説明

目次Vueのリスナーとは何かリスナーの使い方vue リスナーウォッチVue リスナー - ディープリ...

Nginx におけるサーバーとロケーションのマッチングロジックの詳細な理解

サーバーマッチングロジックNginx は、リクエストを実行するサーバー ブロックを決定するときに、サ...

Linux システムに docker をインストールし、ssh 経由で docker コンテナにログインする方法

注: 私はCentosを使ってdockerをインストールしていますステップ1: Dockerをインス...

Mybatis mysqlの削除操作では、最初のデータメソッドのみを削除できます。

バグ図のように、削除文とパラメータをデータベースにコピーして実行し、2つのデータを削除しようとしたの...

MySQL におけるデフォルトの使用法の詳細な説明

NULL および NOT NULL 修飾子、DEFAULT 修飾子、AUTO_INCREMENT 修...

WeChatアプレットで計算機機能を実装する

この記事は、WeChat アプレットを使用して作成された簡単な計算機です。興味のある方はご覧ください...

TypeScript における型保護の詳細な説明

目次概要型アサーション構文ではインスタンスオブ構文typeof構文要約する概要TypeScript ...

最も完全なpackage.json分析

目次1. 概要2. 名前フィールド3. バージョンフィールド4. 説明フィールド5. キーワードフィ...

ネイティブ js カプセル化シームレスカルーセル機能

ネイティブjsカプセル化シームレスカルーセルプラグイン、参考までに、具体的な内容は次のとおりです。例...

mysql の存在する例と存在しない例の詳細な説明

mysql の存在する例と存在しない例の詳細な説明テーブルA |列1 | 列1 | 列3 |テーブル...