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 コマンドを使用する詳細なチュートリアル

推薦する

CSSはletter-spacingプロパティを通じて単語間の間隔を制御します。

letter-spacing プロパティ: 文字間のスペース (文字間隔) を増減します。このプロ...

プロファイルを使用して遅い SQL を分析する MySQL の詳細な説明 (グループ左結合はサブクエリよりも効率的です)

プロファイルを使用して遅いSQLを分析するMySQL の SQL パフォーマンス アナライザーの主な...

Js における new 演算子の役割の詳細な説明

序文Js は現在最も一般的に使用されているコード操作言語であり、その中でも new 演算子は特によく...

MySQL サブクエリとグループ化されたクエリ

目次概要サブクエリサブクエリの分類クエリの結果によるとサブクエリの位置で区別する選択後のサブクエリサ...

Vue のドロップダウン ボックスのセカンダリ リンク効果を実装するためのサンプル コード

1. 成果を達成する 2. バックエンドから返されるデータ形式 「リスト」: [ { "i...

MySQL インデックスが失敗するいくつかの状況の概要

1. インデックスはnull値を保存しないより正確に言うと、単一列インデックスには null 値は格...

CSSはコーナーカット+ボーダー+投影+コンテンツ背景色のグラデーション効果を実現します

CSS を使用するだけで、コーナーカット + ボーダー + 投影 + コンテンツの背景色のグラデーシ...

HTML でナンバープレート番号と州の略語を入力するためのサンプルコード

原理としては、まずボタン付きの div を記述し、次に画面のサイズに応じて自動的に適応してキーボード...

標準的なHTMLの書き方は、Dreamweaverによって自動的に生成されるものとは異なります。

コードをコピーコードは次のとおりです。 <!--doctype はドキュメント タイプ htm...

Ubuntu 18.04 向け VMware Tools のインストールと構成のチュートリアル

この記事では、Ubuntu 18.04でのVMware Toolsのインストールと設定について記録し...

HTML で Web ページに動的な時計を書く

HTML を使用して動的な Web クロックを作成します。コードは次のとおりです。 <!DOC...

サラウンドリフレクションロード効果を実現するHTML+CSS

この記事では、主に html + css を使用してサラウンド リフレクション ローディング エフェ...

CSS の歪んだ影の実装コード

この記事では、CSS ワープ シャドウの実装コードを紹介し、皆さんと共有します。詳細は以下の通りです...

MySQL トリガーの使用方法と利点と欠点の紹介

目次序文1. トリガーの概要2. トリガーの作成2.1 トリガー構文の作成2.2 コード例3. トリ...

Alibaba Cloud Centos 7.5 に MySQL をインストールするチュートリアル

CentOS 7 の yum ソースには、MySQL を正常にインストールするための mysql-s...