ミニプログラムでログイン機能を実装する方法の簡単な分析

青灯夜游
リリース: 2021-12-06 10:13:11
転載
4088 人が閲覧しました

ミニプログラムにログイン機能を実装するにはどうすればよいですか?この記事では、ミニプログラムのログインを開く正しい方法を紹介します。

ミニプログラムでログイン機能を実装する方法の簡単な分析

ミニ プログラム ネットワーク コンポーネント

https://developers.weixin.qq.com/miniprogram /dev/api/network/request/wx.request.html

リクエストタスクの説明

#メソッド 説明リクエスト タスクを中止します。 HTTP 応答ヘッダー イベントをリッスンします。リクエスト完了イベントよりも早く発生します。 HTTP 応答ヘッダー イベントのリスニングをキャンセルします。 Transfer-Encoding Chunk Received イベントをリッスンします。新しいチャンクを受信したときに発生します。 Transfer-Encoding Chunk Received イベントのリスニングをキャンセルします。
RequestTask.abort()
RequestTask.onHeadersReceived(関数コールバック)
RequestTask.offHeadersReceived(関数コールバック)
RequestTask.onChunkReceived(関数コールバック)
RequestTask.offChunkReceived(関数コールバック)

wx.request(Object object) 属性

ここでは、より一般的に使用される属性のみをリストします。すべての属性リンクを参照してください。

#属性url 開発者サーバー インターフェイスのアドレスですstring/object/ArrayBufferNoObject デフォルトは numbermethodstringGETNoHTTP リクエスト メソッド成功関数failfunction#completefunction##NoInterface コールバック関数中止されたリクエストであっても、通話を終了します (通話が成功または失敗した場合に実行されます)。
タイプ デフォルト値 必須 説明
string ## は
#data

リクエストされたパラメータ
header
##No リクエストされたヘッダーを設定します。ヘッダーにはリファラーを含めることはできませんセット。
content-type
application/json timeout
##No ミリ秒単位のタイムアウト
No インターフェイス呼び出しが成功した場合のコールバック関数
No コールバック関数インターフェイス呼び出し失敗の場合

要約すると、すべてのミニ プログラム インターフェイスには基本的に次の 2 つの特性があります:

パラメータ すべてはオブジェクトです。覚えやすく、拡張も簡単です。

    はすべて同じ結果処理メソッドを持ち、すべてに 3 つのコールバック属性 (success、fail、complete) があります。
  • インターフェイスが実行されるときのさまざまな状況における errMsg オブジェクトの紹介。

#コールバック属性errMsg オブジェクト

成功{errMsg:"request:ok"...}fail{errMsg:"request:fail "...} 一部のシステムではこれが発生します失敗の後にはスペースがあるため、この判断を使用するには正規表現を使用するのが最適です。また、indexOf 関数を使用して、-1 より大きいかどうかを判断することもできます。 abort{errMsg:"request:fail abort"...}

サンプル コード

  let reqTask = wx.request({
      url: getApp().globalData.api,
      success(res) {
        if (res.errMsg === "request:ok") console.log("res", res);
      },
      fail(err) {
        // if(err.errMsg.indexOf('request:fail')>-1) console.log('err', err);
        if (/^request:fail/i.test(err.errMsg)) console.log("err", err);
      },
      complete(res) {
        console.log("resOrErr", res);
      },
    });
   const reqTaskOnHeadersReceived = (headers) => {
      reqTask.offHeadersReceived(reqTaskOnHeadersReceived);
      console.log("headers", headers);
      // 由于请求还未完全结束,所以我们没办法获得请求的状态码,但是我们可以通过返回的requestBody的长度来进行判断。
      // 两点说明:1. 两个~~可以把字符串数字快速转化为数字。
      // 2. 为什么取小于19,是由于后台返回没有权限的requestBody的时候Content-length为“18”,正常情况下是大于19的。所以具体多少得看一下具体情况。
      if (~~headers.header["Content-length"] < 19) reqTask.abort();
    };
    reqTask.onHeadersReceived(reqTaskOnHeadersReceived);
ログイン後にコピー

ミニ プログラム ログイン インターフェイス

  • ##wx 。 getUserProfile(Object object)#ユーザー情報を取得します。これは、ページ上でクリック イベントが生成された後にのみ呼び出すことができます (たとえば、

    button

    bindtap のコールバック内)。リクエストごとに認証ウィンドウがポップアップ表示され、 userInfo は、ユーザーが同意した後に返されます。このインターフェイスは、wx.getUserInfo を置き換えるために使用されます。詳細については、ユーザー情報インターフェイスの調整手順を参照してください。

  • wx.checkSession(Object object)

    ログイン状態の有効期限が切れているかどうかを確認します。 wx.login インターフェースを通じて取得されるユーザーのログインステータスには、一定の適時性があります。ユーザーがミニ プログラムを使用していない期間が長いほど、ユーザーのログイン ステータスが無効になる可能性が高くなります。一方、ユーザーがミニプログラムを使用している場合、ユーザーのログイン状態は常に有効のままです。特定のタイミング ロジックは WeChat によって維持され、開発者には透過的です。開発者は、wx.checkSession インターフェイスを呼び出して、現在のユーザーのログイン ステータスが有効かどうかを確認するだけで済みます。

    ログイン状態の有効期限が切れた後、開発者は wx.login を呼び出して新しいユーザーのログイン状態を取得できます。呼び出しが成功した場合は、現在の session_key の有効期限が切れていないことを示し、呼び出しが失敗した場合は、session_key の有効期限が切れたことを示します。その他の利用方法については、

    ミニプログラムログイン

    をご覧ください。

  • wx.login(Object object)

    インターフェースを呼び出して、ログイン資格情報 (コード) を取得します。ユーザーのログイン ステータス情報はバウチャーを通じて交換されます。これには、現在のミニ プログラムでのユーザーの一意の ID (openid)、WeChat オープン プラットフォーム アカウントでの一意の ID (現在のミニ プログラムが WeChat オープン プラットフォームにバインドされている場合は、unionid) が含まれます。アカウント)とこのログイン、セッションキー(session_key)など。ユーザーデータ通信の暗号化と復号化はセッションキーに依存します。その他の利用方法については、

    ミニプログラムログイン

    をご覧ください。

#バックエンド ログイン インターフェイス コードの実装

バックエンドは、NodeJS、Web フレームワーク KOA バージョン ^2.13 を使用します。 4、ルーティング フレームワーク @koa/router バージョン ^10.1.1、フレームワーク リクエスト、バージョン ^2.88.2、トークン情報の暗号化と復号化に jsonwebtoken が使用されます、バージョン ^8.5.1

// app.js
const Koa = require("koa");
const Router = require("@koa/router");
const WeixinAuth = require("./lib/koa2-weixin-auth");
const jsonwebtoken = require("jsonwebtoken");

const app = new Koa();
// 小程序机票信息
const miniProgramAppId = "*********";
const miniProgramAppSecret = "***********";
const weixinAuth = new WeixinAuth(miniProgramAppId, miniProgramAppSecret);

const JWT_SECRET = "JWTSECRET";
// 路由中间件需要安装@koa/router
// 开启一个带群组的路由
const router = new Router({
  prefix: "/user",
});
// 这是正规的登陆方法
// 添加一个参数,sessionKeyIsValid,代表sessionKey是否还有效
router.post("/weixin-login", async (ctx) => {
  let { code, userInfo, encryptedData, iv, sessionKeyIsValid } =
    ctx.request.body;
   // 解析openid
  const token = await weixinAuth.getAccessToken(code);
  userInfo.openid = token.data.openid;
  // 这里可以自己进行处理,比方说记录到数据库,处理token等
  let authorizationToken = jsonwebtoken.sign(
    { name: userInfo.nickName },
    JWT_SECRET,
    { expiresIn: "1d" }
  );
  Object.assign(userInfo, { authorizationToken });
  ctx.status = 200;
  ctx.body = {
    code: 200,
    msg: "ok",
    data: userInfo,
  };
});
ログイン後にコピー
// lib/koa2-weixin-auth.js
const querystring = require("querystring");
const request = require("request");

const AccessToken = function (data) {
  if (!(this instanceof AccessToken)) {
    return new AccessToken(data);
  }
  this.data = data;
};

/*!
 * 检查AccessToken是否有效,检查规则为当前时间和过期时间进行对比
 *
 * Examples:
 * ```
 * token.isValid();
 * ```
 */
AccessToken.prototype.isValid = function () {
  return (
    !!this.data.session_key &&
    new Date().getTime() < this.data.create_at + this.data.expires_in * 1000
  );
};

/**
 * 根据appid和appsecret创建OAuth接口的构造函数
 * 如需跨进程跨机器进行操作,access token需要进行全局维护
 * 使用使用token的优先级是:
 *
 * 1. 使用当前缓存的token对象
 * 2. 调用开发传入的获取token的异步方法,获得token之后使用(并缓存它)。

 * Examples:
 * ```
 * var OAuth = require('oauth');
 * var api = new OAuth('appid', 'secret');
 * ```
 * @param {String} appid 在公众平台上申请得到的appid
 * @param {String} appsecret 在公众平台上申请得到的app secret
 */
const Auth = function (appid, appsecret) {
  this.appid = appid;
  this.appsecret = appsecret;
  this.store = {};

  this.getToken = function (openid) {
    return this.store[openid];
  };

  this.saveToken = function (openid, token) {
    this.store[openid] = token;
  };
};

/**
 * 获取授权页面的URL地址
 * @param {String} redirect 授权后要跳转的地址
 * @param {String} state 开发者可提供的数据
 * @param {String} scope 作用范围,值为snsapi_userinfo和snsapi_base,前者用于弹出,后者用于跳转
 */
Auth.prototype.getAuthorizeURL = function (redirect_uri, scope, state) {
  return new Promise((resolve, reject) => {
    const url = "https://open.weixin.qq.com/connect/oauth2/authorize";
    let info = {
      appid: this.appid,
      redirect_uri: redirect_uri,
      scope: scope || "snsapi_base",
      state: state || "",
      response_type: "code",
    };
    resolve(url + "?" + querystring.stringify(info) + "#wechat_redirect");
  });
};

/*!
 * 处理token,更新过期时间
 */
Auth.prototype.processToken = function (data) {
  data.create_at = new Date().getTime();
  // 存储token
  this.saveToken(data.openid, data);
  return AccessToken(data);
};

/**
 * 根据授权获取到的code,换取access token和openid
 * 获取openid之后,可以调用`wechat.API`来获取更多信息
 * @param {String} code 授权获取到的code
 */
Auth.prototype.getAccessToken = function (code) {
  return new Promise((resolve, reject) => {
    const url = "https://api.weixin.qq.com/sns/jscode2session";
    //由于此框架版本很久没有更新了,此处地址发生了变化,需要修改为以上地址,不然会出现
    //41008错误。这也是没有直接使用框架,引用本地使用的原因。
    // const url = "https://api.weixin.qq.com/sns/oauth2/access_token";
    const info = {
      appid: this.appid,
      secret: this.appsecret,
      js_code: code,
      grant_type: "authorization_code",
    };
    request.post(url, { form: info }, (err, res, body) => {
      if (err) {
        reject(err);
      } else {
        const data = JSON.parse(body);
        resolve(this.processToken(data));
      }
    });
  });
};

/**
 * 根据refresh token,刷新access token,调用getAccessToken后才有效
 * @param {String} refreshToken refreshToken
 */
Auth.prototype.refreshAccessToken = function (refreshToken) {
  return new Promise((resolve, reject) => {
    const url = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
    var info = {
      appid: this.appid,
      grant_type: "refresh_token",
      refresh_token: refreshToken,
    };
    request.post(url, { form: info }, (err, res, body) => {
      if (err) {
        reject(err);
      } else {
        const data = JSON.parse(body);
        resolve(this.processToken(data));
      }
    });
  });
};

/**
 * 根据openid,获取用户信息。
 * 当access token无效时,自动通过refresh token获取新的access token。然后再获取用户信息
 * @param {Object|String} options 传入openid或者参见Options
 */
Auth.prototype.getUser = async function (openid) {
  const data = this.getToken(openid);
  console.log("getUser", data);
  if (!data) {
    var error = new Error(
      "No token for " + options.openid + ", please authorize first."
    );
    error.name = "NoOAuthTokenError";
    throw error;
  }
  const token = AccessToken(data);
  var accessToken;
  if (token.isValid()) {
    accessToken = token.data.session_key;
  } else {
    var newToken = await this.refreshAccessToken(token.data.refresh_token);
    accessToken = newToken.data.session_key;
  }
  console.log("accessToken", accessToken);
  return await this._getUser(openid, accessToken);
};

Auth.prototype._getUser = function (openid, accessToken, lang) {
  return new Promise((resolve, reject) => {
    const url = "https://api.weixin.qq.com/sns/userinfo";
    const info = {
      access_token: accessToken,
      openid: openid,
      lang: lang || "zh_CN",
    };
    request.post(url, { form: info }, (err, res, body) => {
      if (err) {
        reject(err);
      } else {
        resolve(JSON.parse(body));
      }
    });
  });
};

/**
 * 根据code,获取用户信息。
 * @param {String} code 授权获取到的code
 */
Auth.prototype.getUserByCode = async function (code) {
  const token = await this.getAccessToken(code);
  return await this.getUser(token.data.openid);
};

module.exports = Auth;
ログイン後にコピー

ミニプログラムターミナルのログインコードの実装



    微信登录
    
        
    
ログイン後にコピー
// pages/index.js
Page({
  /**
   * 页面的初始数据
   */
  data: {},
  // 正确的登录方式
  getUserProfile() {
    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
    // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    wx.getUserProfile({
      desc: "用于完善会员资料", // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        let { userInfo, encryptedData, iv } = res;
        const requestLoginApi = (code) => {
          // 发起网络请求
          wx.request({
            url: "http://localhost:3000/user/weixin-login",
            method: "POST",
            header: {
              "content-type": "application/json",
            },
            data: {
              code,
              userInfo,
              encryptedData,
              iv,
            },
            success(res) {
              console.log("请求成功", res.data);
              let token = res.data.data.authorizationToken;
              wx.setStorageSync("token", token);
              onUserLogin(token);
              console.log("authorization", token);
            },
            fail(err) {
              console.log("请求异常", err);
            },
          });
        };
        const onUserLogin = (token) => {
          getApp().globalData.token = token;
          wx.showToast({
            title: "登录成功了",
          });
        };
        //必须进行session是否过期检查,不然会出现第一次点击登录,服务器报Illegal Buffer
        //的错误,但是第二次点击登录正常。
        wx.checkSession({
          success: (res) => {
            // session_key 未过期,并且在本生命周期一直有效
            console.log("在登陆中");
            let token = wx.getStorageSync("token");
            if (token) onUserLogin(token);
          },
          fail: (res) => {
            // session_key已经失效,需要重新执行登录流程
            wx.login({
              success(res0) {
                if (res0.code) {
                  requestLoginApi(res0.code);
                } else {
                  console.log("登录失败!" + res0.errMsg);
                }
              },
            });
          },
        });
      },
    });
  },
});
ログイン後にコピー

ログインコードに対してどのような最適化が可能ですか?

ソフトウェアの場合、コード レベルで最も基本的な側面を追求する必要があります (これらよりもはるかに多くの側面がありますが、最初にこれらの側面をしっかりと理解しましょう):

Maintainability (保守性)
  • いわゆる「メンテナンス」とは、バグを修正したり、古いコードを修正したり、新しいコードを追加したりする作業にほかなりません。いわゆる「コードの保守が容易である」とは、元のコード設計を破壊したり、新しいバグを導入したりすることなく、コードを迅速に変更または追加できることを意味します。いわゆる「コードの保守が容易ではない」とは、コードの変更や追加には新たなバグが発生する大きなリスクがあり、完了までに長い時間がかかることを意味します。

    可読性 (可読性)
  • ソフトウェア設計の第一人者、マーティン・ファウラーはかつてこう言いました。 .」 中国語訳:「どんな愚か者でもコンピュータが理解できるコードを書くことができる。優れたプログラマは人間が理解できるコードを書くことができる。」 Google 内には Readability と呼ばれる認定資格さえあります。この認定を取得したエンジニアのみが、コードレビュー中に他の人がコードを提出することを承認する資格を持ちます。コードの読みやすさがいかに重要であるかがわかりますが、結局のところ、コードが書かれて実行される回数よりも読み取られる回数のほうがはるかに多いのです。コードがコーディング規約に準拠しているか、意味のあるネーミングか、コメントが詳細か、関数の長さは適切か、モジュール分けは明確か、高凝集性・低結合性を満たしているかなどを確認する必要があります。

    拡張性 (拡張性)
  • 拡張性も、コードの品質を評価するための非常に重要な基準です。コードにはいくつかの関数拡張ポイントが確保されており、関数を追加するためだけに多大な労力を費やして元のコードを大幅に変更することなく、新しい関数コードを拡張ポイントに直接挿入できます。

    再利用性
  • 代码的可复用性可以简单地理解为,尽量减少重复代码的编写,复用已有的代码。

那么接下来就来优化一下代码吧:

模块化

可以把登录的代码模块化,代码如下:

// lib/login.js
function loginWithCallback(cb) {
  // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
  // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
  wx.getUserProfile({
    desc: "用于完善会员资料", // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
    success: (res) => {
      let { userInfo, encryptedData, iv } = res;
      const requestLoginApi = (code) => {
        // 发起网络请求
        wx.request({
          url: "http://localhost:3000/user/weixin-login",
          method: "POST",
          header: {
            "content-type": "application/json",
          },
          data: {
            code,
            userInfo,
            encryptedData,
            iv,
          },
          success(res) {
            console.log("请求成功", res.data);
            let token = res.data.data.authorizationToken;
            wx.setStorageSync("token", token);
            onUserLogin(token);
            console.log("authorization", token);
          },
          fail(err) {
            console.log("请求异常", err);
          },
        });
      };

      const onUserLogin = (token) => {
        getApp().globalData.token = token;
        wx.showToast({
          title: "登录成功了",
        });
        if (cb && typeof cb == "function") cb(token);
      };
      wx.checkSession({
        success: (res) => {
          // session_key 未过期,并且在本生命周期一直有效
          console.log("在登陆中");
          let token = wx.getStorageSync("token");
          if (token) onUserLogin(token);
        },
        fail: (res) => {
          // session_key已经失效,需要重新执行登录流程
          wx.login({
            success(res0) {
              if (res0.code) {
                requestLoginApi(res0.code);
              } else {
                console.log("登录失败!" + res0.errMsg);
              }
            },
          });
        },
      });
    },
  });
}

export default loginWithCallback;
ログイン後にコピー

Promise化

回调地狱问题,不利于代码的阅读,所以接下来我们基于Promise进行代码优化。有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。

Promise的几个方法简介

#メソッド名説明##Promise.prototype.thenPromise.prototype.catchPromise.prototype.finally#Promise.allthen()Promise.racePromise.anyPromise.allSettledrejected# された場合に値を返します。 ## の後の Promise にはオブジェクトの配列が伴い、各オブジェクトは対応する Promise の結果を表します。対照的に、
このメソッドは新しい Promise オブジェクトを返すため、連鎖的に記述することができます。この設計により、コールバック関数の「水平開発」から「下方開発」まで、ネストされた非同期操作を簡単に書き直すことができます。
は、Promise.prototype.then(null、rejection) のエイリアスで、エラーがいつ発生するかを指定するために使用されます。コールバックが発生します。 Promise オブジェクトのエラーには「バブル」の性質があり、検出されるまで逆方向に伝播します。つまり、エラーは常に次の catch ステートメントによってキャッチされます。
メソッドは Promise を返します。 Promise の終了時には、結果が満たされたか拒否されたかに関係なく、指定されたコールバック関数が実行されます。これにより、Promise が正常に完了するかどうかに関係なく、コードを実行する必要がある方法が提供されます。
これにより、## で同じステートメントを使用する必要がなくなります。 # と catch() はそれぞれ 1 回ずつ書き込まれます。 Promise.all メソッドは、複数の Promise インスタンスを新しい Promise インスタンスにラップするために使用されます。 Promise.all メソッドは配列をパラメーターとして受け入れます。 var p = Promise.all([p1,p2,p3]);p1、p2、p3 はすべて Promise オブジェクトのインスタンスです。 (Promise.all メソッドのパラメーターは必ずしも配列である必要はありませんが、イテレーター インターフェイスが必要であり、返される各メンバーは Promise インスタンスです。) p の状態は、p1、p2、および p3 によって決定され、次のように分割されます。 2つの状況。 (1) p1、p2、p3 の状態がすべて満たされた場合にのみ、p の状態が満たされます このとき、p1、p2、p3 の戻り値は配列を形成し、 pのコールバック関数。 (2) p1、p2、p3 のいずれかが拒否されると、p の状態は拒否されますが、このとき最初に拒否されたインスタンスの戻り値が p のコールバック関数に渡されます。
Promise.race メソッドは、複数の Promise インスタンスを新しい Promise インスタンスにラップします。 var p = Promise.race([p1,p2,p3]);上記のコードでは、p1、p2、p3 のうちの 1 つのインスタンスが最初に状態を変更する限り、p の状態が変更されます。それに応じて。 pの戻り値には、最初に変更されたPromiseインスタンスの戻り値が渡されます。
Promise 反復可能オブジェクトを受け取り、Promise の 1 つが成功する限り、成功した Promise が返されます。すべてのサブインスタンスは拒否された状態になり、Promise 全体も拒否された状態になります。
指定されたすべての Promise が fulfilled または Promise.all() は、相互の依存関係、またはいずれかの依存関係が reject になったときにすぐに終了する場合により適しています。

小程序API接口Promise化并且把需要登录的调用接口模块化

1、安装插件。请先查看npm支持文档。

npm install --save miniprogram-api-promise
ログイン後にコピー

2、在微信开发者工具右方详情中勾选使用npm模块,并在菜单栏工具中点击构建npm。

3、初始化代码。

// app.js
import {promisifyAll} from 'miniprogram-api-promise'
import login from "../lib/login";
const wxp ={}
promisifyAll(wx,wxp)
// 需要token的请求统一处理登录和设置header,并且处理错误信息
wxp.requestNeedLogin = async function (args) {
  let token = wx.getStorageSync("token");
  if (!token) {
    token = await loginWithPromise();
  }
  if (!args.header) args.header = {};
  args.header["Authorization"] = `Bearer ${token}`;
  return wxp.request(args).catch(console.error);
};
// app.js
App({
  wxp:wxp,
});
ログイン後にコピー

4、改写login.js代码

// lib/login.js
function login() {
  return new Promise((resolve, reject) => {
    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
    // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    wx.getUserProfile({
      desc: "用于完善会员资料", // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
       success:async (res0) => {
        let {
          userInfo,
          encryptedData,
          iv
        } = res0;
        const app = getApp();
        try {
          app.wxp.checkSession();
        } catch (err) {
          reject(err);
        }
        let token = wx.getStorageSync("token");
        if (!token) {
          let res1 = await app.wxp.login().catch(err => reject(err));
          let code = res1.code;
          let res = await app.wxp.request({
            url: "http://localhost:3000/user/weixin-login",
            method: "POST",
            header: {
              "content-type": "application/json",
            },
            data: {
              code,
              userInfo,
              encryptedData,
              iv,
            }
          }).catch(err => reject(err));
          token = res.data.data.authorizationToken;
          wx.setStorageSync("token", token);
          app.globalData.token = token;
          wx.showToast({
            title: "登录成功了",
          });
          resolve(token);
        }
      },
    });
  })
}

export default login;
ログイン後にコピー

5、调用代码


  需要登录的请求调用
  
    
    
  
ログイン後にコピー
// pages/index.js
Page({
  /**
   * 页面的初始数据
   */
  data: {},
  request1() {
    getApp().wxp.requestNeedLogin({
        url: "http://localhost:3000/user/home?name=andying",
      }).then(console.log)
  },
  request2() {
    getApp().wxp.requestNeedLogin({
        url: "http://localhost:3000/user/home?name=eva",
      }).then(console.log)
  },
});
ログイン後にコピー

【相关学习推荐:小程序开发教程

以上がミニプログラムでログイン機能を実装する方法の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!