WeChatアプレットのサイレントログインとカスタムログイン状態の維持の詳細な説明

WeChatアプレットのサイレントログインとカスタムログイン状態の維持の詳細な説明

1. 背景

ミニプログラムでは、openid はミニプログラム/パブリック アカウントのユーザー識別子です。開発者は、ID カードと同様に、この識別子を通じてユーザーを識別できます。

2. サイレントログインとは何ですか?

一般的なアプリケーションでは、ユーザーはフォーム認証を通じてログインし、ユーザー システムを確立します。この一般的なログイン方法は、通常、ユーザーの目に留まるログイン ページ フォームを通じて行われます。

ミニプログラムはWeChatをベースにしているため、WeChatが公式に提供しているAPI機能を使用して、無意識のうちにユーザーID(OpenID)を取得し、ミニプログラム内でユーザーシステムを迅速に構築できます。これはユーザーには認識されず、プログラムが自動的にログインプロセスを完了します。

2.1 ログインプロセスのシーケンス

以下の写真はWeChat公式から引用したものです

アプレットはwx.login()を呼び出してコードを取得し、サーバーにアップロードします。

非同期関数doLogin()をエクスポートします。
 if (isLogin) が false を返す
 ログイン = true
 キャッシュを削除します('トークン')
 const { コード } = wxp.login() を待機します
 const データ = ログインを待機します ({ コード })
 setCache('トークン', data.data.token)
 ログイン = false
 真を返す
}

サーバーはコードを取得し、auth.code2Sessionインターフェースを呼び出してopenidと交換します。
const getOpenid = 非同期関数 (appid, secret, code) {
    const resData = axios.get('https://api.weixin.qq.com/sns/jscode2session?appid=' + appid + '&secret=' + secret + '&js_code=' + code + '&grant_type=authorization_code');
    resData.data を返します。
}

プロセスを要約します。

  • アプレットはwx.login()を呼び出してコードを取得し、サーバーにアップロードします。
  • サーバーはコードを使用し、WeChat auth.code2Sessionインターフェースを呼び出してopenidと交換します。
  • バックエンドサーバーはOpenIDに基づいてカスタムトークンを生成し、フロントエンドに返して保存します。後続のビジネスロジックはトークンを使用してユーザーを識別します。

3. カスタムログイン状態を維持する方法

公式のアプローチを見てみましょう:

wx.checkSession({
  成功 () {
    //session_key は期限切れではなく、このライフサイクル全体を通じて有効です},
  失敗 () {
    //session_key の有効期限が切れているため、ログイン プロセスを再実行する必要があります wx.login() //Re-login}
})

図から、実際にログイン状態を決定するのは WeChat の checkSession インターフェースであることがわかります。したがって、ユーザーのログイン ステータスが有効かどうかを確認するたびに、まず checkSession インターフェイスを呼び出します。session_key が無効な場合は、ログイン プロセスを開始します。

4. サイレントログインの全体的なプロセス

4.1 app.onLaunchでログインが開始される

ほとんどの API 呼び出しではトークンの検証が必要なので、ミニプログラムの起動時に定期的な関数 app.onLaunch でサイレント ログインを開始するのが最も適切です。

4.2 処理アプレットは非同期ブロッキングをサポートしていません

ページレベルおよびコンポーネントレベルのライフサイクル関数は、ミニプログラムの起動プロセスでの非同期ブロッキングをサポートしていないため、app.onLaunch で開始された wx.login が成功する前に、ページレベルのライフサイクル関数が既にサーバーへの要求を開始している状況が発生する可能性があります。ほとんどのインターフェース設計では検証が必要なため、この時点ではログインは成功しておらず、トークンが正しく返されていないため、ページレベルのライフサイクルによって開始されたデータ取得インターフェースは必ずエラーを報告します(たとえば、401が返されます)。

4.2.1 大まかな解決策

コールバック関数の使用

//アプリ.js
this.globalData.wxp.showLoading({
        タイトル: 「ログイン中...」
      });
      ログインを待機します();
      this.globalData.hasLogin = true;
      if (this.checkLoginReadyCallback) {
        this.checkLoginReadyCallback();
      }
      this.globalData.wxp.hideLoading();
      
ページのライフサイクルでは、async onLoad() {
    app.globalData.hasLogin の場合 {
    //すでにログインしている場合は、データを直接取得します this.getUserInfo();
      イベントを取得します。
    } それ以外 {
    // ログインしていないときのコールバック関数を定義し、app.js が正常にログインした後に呼び出します app.checkLoginReadyCallback = async () => {
        this.getUserInfo();
        イベントを取得します。
      };
    }
  },

利点: シンプルで粗雑

デメリット: コード構造が貧弱。複数のページがスタートアップ ページである場合、複数のページに対してコールバック関数を定義する必要があります (ミニ プログラム onShare モードが使用されていると仮定)

4.2.2 エレガントな方法

fly.js ライブラリの助けを借りて、リクエストのロック メカニズムが実装されます。プロセス: app.js でログインが開始され、ページでもリクエストが開始されます。リクエスト インターセプターでは、要求されたインターフェイスがホワイトリスト (トークン検証を必要としないインターフェイス) にあるかどうか、およびインターフェイスとトークンが存在するかどうかを判断します。両方とも false の場合は、現在のリクエストをリクエスト キューにロックし、ログイン プロセスを実行します。ログイン プロセスが成功するまで待機した後、要求キューのロックを解除し、ページ レベルの要求タスクの開始を続行します。以下はリクエスト インターセプターのコードです。

//インターセプト処理 fly.interceptors.request.use(async (request) => {
	// トークンがなくホワイトリストにないリクエストはすべてロックされます (
		!getCache('トークン') &&
		!whiteList.some((item) => request.url.startsWith(item))
	){
		フライ.ロック()
		//ログイン成功後にロックを解除する
		ログインを待つ()
		fly.unlock() //ロック解除後、リクエストキュー内のタスクは引き続き開始されます }

	if (getCache('token') && !fly.config.headers['Authorization']) {
		request.headers['Authorization'] = getCache('token')
	}
	request.headers['Content-Type'] = 'application/x-www-form-urlencoded'

	返品リクエスト
})

もちろん、カスタム ログイン状態も期限切れになる場合があります。処理のために、応答インターセプターでエラーをキャプチャできます。401 トークン有効期限コードが検出されると、リクエスト キューの背後にあるすべてのリクエストをロックして、複数の 401 カスタム ログイン状態の有効期限が切れないようにする必要があります。次に、ログインを開始し、ログインが成功した後にロックを解除して、後続のリクエスト キューの実行をトリガーし、トークンの有効期限切れのためにサーバーによって拒否されたインターフェイスを再実行します。そうしないと、リクエストは失敗します (サイレント ログインはユーザーには認識されないため、認証情報の突然の有効期限切れはユーザーに特に違和感を与えるため、ユーザーがもう一度クリックしたり、他のアクションで開始したりするのではなく、このリクエスト操作を再実行する必要があります)。

// レスポンスインターセプション fly.interceptors.response.use(
	(応答) => {
		//リクエスト結果のデータフィールドのみを返す。response.dataを返す
	},
	非同期(エラー) => {
		(エラーステータス === 401)の場合{
			//401の後、それ以降のすべてのリクエストは再び401にならないようにロックされます
			フライ.ロック()
			キャッシュを削除します('トークン')
			//ログイン成功後にロックを解除する
			const isLoginSuccess = doLogin() を待つ
			ログイン成功の場合
				フライ.ロック解除()
			}
                        // トークンの有効期限切れによりサーバーに拒否されたインターフェースを新たに実行する return fly.request(err.request)
		}
	}
)

リクエストが同時に発生する可能性があるため、ログインが複数回実行されるのを防ぐために、doLogin 関数を少し変更します (エレガントに記述されているわけではありませんが、私の能力には限界があるため、ご教示ください)。

非同期関数doLogin()をエクスポートします。
        //ログイン中の場合は実行しない if (isLogin) return false
	ログイン = true
        // ステータスをログイン済みに変更します。とにかく、複数回ログインします。removeCache('token')
	const { コード } = wxp.login() を待機します
	const データ = ログインを待機します ({ コード })
	setCache('トークン', data.data.token)
	ログイン = false
	真を返す
}

4.3 全体フローチャート

5. 最後に

詳細に注意を払う読者は、API リクエストに設定されたリクエストの最大数がないことに気付くでしょう (WeChat ミニプログラムは、最大 5 つの API の同時開始をサポートします)。これを補足する必要があります。全体的に、実装方法にはまだ改善の余地があると感じています。著者の能力には限界があるため、学習と議論も同時に行っています。

これで、WeChatミニプログラムのサイレントログインとカスタムログインステータスの維持に関するこの記事は終了です。WeChatミニプログラムのサイレントログインに関する関連コンテンツの詳細については、123WORDPRESS.COMの以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も123WORDPRESS.COMを応援してください。

以下もご興味があるかもしれません:
  • WeChat アプレットサイレントログイン実装コード

<<:  Linux で Redis のリモート接続を実装する方法

>>:  Java は Excel から MySQL にデータをインポートします

推薦する

docker compose を使ってワンクリックで分散構成センター Apollo を展開するプロセスの詳細な説明

導入分散について話すときは、分散構成センター、分散ログ、分散リンク トラッキングなどについて考える必...

Dockerがコンテナを作成した後にホスト名を変更する詳細なプロセス

後悔を癒す薬は世の中にある、考えてみる気さえあれば!コンテナを再作成する必要はもうありません。 m2...

Vue デフォルトスロットの理解とサンプルコード

目次スロットとは何かデフォルトスロットの理解コードスニペット要約するスロットとは何かスロットは、親コ...

Jenkins でユーザー ロールの権限を設定する方法

Jenkinsのユーザーロール権限の設定には、ロール戦略プラグインのインストールが必要です。 1.ロ...

スライドボタン効果を実現するネイティブJS

Jsで作ったスライドボタンの具体的なコードは参考までに。具体的な内容は以下のとおりですまずエフェク...

Vue のプロダクション環境と開発環境を切り替えてフィルターを使用する方法

目次1. 本番環境と開発環境を切り替える最初の方法: .envファイルを設定する2番目の方法2. フ...

ウェブページを作る前に、これらのいわゆる仕様を見てみましょう

この記事では、Web ページを作成する前に確認すべき、いわゆる仕様をいくつかまとめました。皆様のお役...

MySQL Limitパフォーマンス最適化とページングデータパフォーマンス最適化の詳細な説明

MySQL Limit はセグメント内のデータベース データをクエリでき、主にページングで使用されま...

MySQLはIDに適切なデータ型を選択します

目次分散IDソリューションの概要データベース自動増分IDデータベースマルチマスターモード数値セグメン...

負荷分散と動的および静的分離操作を実現するDocker NginxコンテナとTomcatコンテナ

Tomcat8 イメージをダウンロード [root@localhost ~]# docker sea...

MySQLのインデックス

序文早速本題に入りましょう。これからお話しするのは次のマインドマップです。まずは印象をつかんでくださ...

Nacos で MySQL8 を設定する方法

1. MySQLデータベースnacos_configを作成する2. データベース nacos_con...

nginx をベースにした Web クラスター プロジェクトをすばやく構築する方法を説明します。

目次1. プロジェクト環境2. プロジェクトの説明3. プロジェクトの手順1. インストール2. 構...

JavaScript で外部変数にアクセスするサブ関数の 3 つのソリューション

序文Web ページを作成するときに、次のような状況に遭遇することはよくあります。 <本文>...

MySQL 圧縮パッケージ版 zip インストール設定方法

圧縮版の記事ではデータの初期化がされていないなどいくつか問題があったため、Windows にインスト...