javaマイクロレターのアプリケーション登録状態の維持を実現するコードの例


多くの開発好きの友達はすでにマイクロクレジットのプログラムがどんな種類かを知っていると信じています。ビルの主も小さい頃からプログラム内測定の時から関心を持っています。でも、基本的には全部書いた純前端です。最近では、ビルの主が後端から前端まで完全なプログラム項目を書いています。途中でいくつかの問題にぶつかりました。
今回は基本的なWeChatウィジェットの登録状態のメンテナンスから始めましょう。プログラム公式アプリドキュメントには登録状態についての完全な説明があり、関連コードがあります。詳細を見たいですが、外に出て右に曲がってもいいです。https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject初めて見た時はよく分かりませんでした。そしてコードはjavaバージョンを提供していません。これはJavaプログラマーの気持ちを何に耐えられるかを研究した後、Javaバージョンの簡単なデモを作ることにしました。
サービスとして、WeChatアプリを利用した会員情報を得るためには、会員の基本情報をクライアントとしてウィジェットが必要です。携帯電話番号と同様に、現在のウィジェットのユーザーの一意のフラグとして機能します。しかし、会員のopenId情報を直接サービス側とウィジェット側を往復すると、安全性に問題があります。万が一他の人にこのopenIdをもらったら、会員の携帯番号をもらうのと同じです。他の操作ができます。明らかに安全ではないです。
この問題を解決するためにWeChatは比較的安全な方法を採用しています。

//app.js
App({
 onLaunch: function() {
  wx.login({
   success: function(res) {
    if (res.code) {
     //      
     wx.request({
      url: 'https://test.com/onLogin',
      data: {
       code: res.code
      }
     })
    } else {
     console.log('         !' + res.errMsg)
    }
   }
  });
 }
})
WeChatアプリケーションはwx.loginのapiを呼び出すことができます。codeを得ることができます。このコードは外部の人にとっては何の意味もありません。安心してサービスに伝えられます。サービスがコードを得たら、あなたがアプリケーションを申請する時のappIdを加えて、app secretでWeChatのインターフェースを調整します。
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_コード
以下のパラメータが得られます。
  • openidユーザ固有識別
  • session_keyセッション鍵
  • unionid本フィールドは、一定の条件を満たす場合には
  • に戻ります。
    その中のopenidは会員の唯一のマークです。この時点でサービス端末は保存できます。
    session_key以降、unionId(全オープンプラットフォーム会員の一意性の表示)を解読するときに有用です。
    サービスがオープンした後、後の相互作用のために保存します。一般的には二つの方法があります。一つは直接データベースに入ること、一つは効率の高いキャッシュを採用することです。スレ主は後者を採用しています。方式はredisです。
    WeChatの提案によると、この場合は、OopenIdの一意の識別として重複しない値を生成する必要がある。ここではjavaのuuidを採用しています。そしてこのuuid値をkeyとして、openidと後に使うsession_keyはvalueとして、redisに保存します。そして、uuid値をウィジェットに返します。このように小さいプログラムは直接uuidの値を持ってサービスと対話することができます。
    もしUuidの値を得たら、openidをもらうのと同じです。会員の唯一の印に相当します。
    ですから、ここではこのuuid値を処理します。まずredisを預け入れる時は時効性があります。session_keyはWeChatサーバーの有効期間は30日間です。サービスエンドキャッシュセッションを提案します。keyは30日間を超えません。ウィジェットからのuuid値が期限切れになったら、これは期限切れのuuidだと思ったら、wx.loginのステップをやり直します。
    redisの中でジョイイスとオプンドの対応関係を便利にするためです。もう一つのopenidはuuidの記録に対応しています。目的は次のwx.loginステップの時にopendによって前の古いuuidを見つけて、存在すれば削除して、新しいuuid値を調べて、opend対応のこの記録も更新します。このようにredisサーバーには余分な汚れがないので、サーバーの負担を軽減します。
    以上は私が理解している登録状態全体の過程です。もちろんwx.checkSessionなどはまだ話していません。実はsessionを発見しました。keyが失効するのは上記の流れをもう一度歩けばいいです。だから詳しく話しませんでした。はっきり言ったかどうか分かりません。全体の流れのキーコードを貼り付けて、参考にします。
    
    @ActionKey("/loginByWeixin")
      public void loginByWeixin() throws Exception {
        logger.info("Start getSessionKey");
        String json = HttpKit.readData(getRequest());
        JSONObject reqJson = JSON.parseObject(json);
        String jsCode = reqJson.getString("code");
        if (jsCode == null || "".equals(jsCode)) {
          logger.info("      ");
          renderJson(new OutRoot().setCode("100").setMsg(SYS.PARAMETER_FAIL));
        } else {
          List<Record> record = appInfoService.selectAppInfo();
          String appId = record.get(0).get("app_id");
          String appSecret = record.get(0).getStr("app_secret");
          if (appId == null || "".equals(appId) || appSecret == null || "".equals(appSecret)) {
            logger.info("      ");
            renderJson(new OutRoot().setCode("100").setMsg(SYS.PARAMETER_FAIL));
          } else {
            String url = "https://api.weixin.qq.com/sns/jscode2session";
            String httpUrl = url + "?appid=" + appId + "&secret=" + appSecret + "&js_code=" + jsCode
                + "&grant_type=authorization_code";
            String ret = HttpRequest.sendGetRequest(httpUrl);
            logger.info("        {}", ret);
            if (ret == null || "".equals(ret)) {
              logger.info("    ");
              renderJson(new OutRoot().setCode("101").setMsg(SYS.CONTACT_FAIL));
            } else {
              JSONObject obj = JSONObject.parseObject(ret);
              if (obj.containsKey("errcode")) {
                String errcode = obj.get("errcode").toString();
                logger.info("        {}", errcode);
                renderJson(new OutRoot().setCode("101").setMsg(SYS.CONTACT_FAIL));
              } else if (obj.containsKey("session_key")) {
                logger.info("     ");
                //     userInfo
                String openId = obj.get("openid").toString();
                Record tbMember = new Record();
                tbMember.set("weixin_openid", openId);
                System.out.println("openId==" + openId);
                //    openId     ,     ,      
                List<Record> memberList = tbMemberService.selectMember(tbMember);
                if (memberList != null && memberList.size() > 0) {
                  logger.info("openId    ,     ");
                } else {
                  JSONObject rawDataJson = reqJson.getJSONObject("userInfo");
                  String nickName = rawDataJson.getString("nickName");
                  String avatarUrl = rawDataJson.getString("avatarUrl");
                  String gender = rawDataJson.getString("gender");
                  String province = rawDataJson.getString("province");
                  String city = rawDataJson.getString("city");
                  String country = rawDataJson.getString("country");
                  tbMember.set("gender", gender);
                  tbMember.set("nick_name", nickName);
                  tbMember.set("avatar_url", avatarUrl);
                  Long openId2 = tbMemberService.addMember(tbMember);
                  logger.info("openId   ,     ");
                }
                // (1)   sessionkey
                String sessionKey = obj.get("session_key").toString();
                logger.info("sessionKey==" + sessionKey);
                logger.info("openId==" + openId);
                // (2)   sessionkey      ,key        uuid
                String rsession = UUID.randomUUID().toString();
                Cache tokenCache = Redis.use("redis_00");
                // (3)     openId,       openId   sessionKey  。
                String oldSeesionKey = tokenCache.getJedis().get(openId);
                if (oldSeesionKey != null && !"".equals(oldSeesionKey)) {
                  logger.info("oldSeesionKey==" + oldSeesionKey);
                  // (4)     openId     
                  tokenCache.getJedis().del(oldSeesionKey);
                  logger.info("  openId    ==" + tokenCache.getJedis().get(oldSeesionKey));
                }
                // (5)       sessionKey: key --> uuid, value --> sessionObj
                JSONObject sessionObj = new JSONObject();
                sessionObj.put("openId", openId);
                sessionObj.put("sessionKey", sessionKey);
                tokenCache.getJedis().set(rsession, sessionObj.toJSONString());
    
                // (6)       openId session     : key --> openId , value --> rsession
                tokenCache.getJedis().set(openId, rsession);
    
                String newOpenId = tokenCache.getJedis().get(openId);
                String newrSession = tokenCache.getJedis().get(rsession);
                logger.info("  openId==" + newOpenId);
                logger.info("  newrSession==" + newrSession);
                // (7)    sessionKey      
                JSONObject objret = new JSONObject();
                objret.put("rdSessionKey", rsession);
                objret.put("errno", 0);
                renderJson(objret);
              }
    
            }
          }
        }
      }
    
    
    プロジェクトの枠组みはJfinalが好きです。javaライト级の急速な开発枠组みはとても高いです。どこか抜けたところがありますか?積極的に意見や批判を出してください。
    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。