Heim  >  Artikel  >  WeChat-Applet  >  Java implementiert die Aufrechterhaltung des Anmeldestatus des WeChat-Applets

Java implementiert die Aufrechterhaltung des Anmeldestatus des WeChat-Applets

不言
不言Original
2018-06-23 13:39:442739Durchsuche

In diesem Artikel wird hauptsächlich der Java-Beispielcode zur Implementierung der Anmeldestatusverwaltung des WeChat-Applets vorgestellt. Er hat einen gewissen Referenzwert.

Ich glaube, dass viele Freunde die Entwicklung mögen Kennen Sie WeChat? Was für Arten sind Miniprogramme? Der Autor hat sich seit der internen Testphase mit Miniprogrammen beschäftigt und auch mehrere WeChat-Miniprogramme geschrieben, die gestartet wurden. Aber im Grunde sind sie nur im Frontend geschrieben. Vor kurzem hat der Poster ein komplettes kleines Programmprojekt vom Back-End bis zum Front-End geschrieben und ist dabei auf einige Punkte gestoßen, die seiner Meinung nach wertvoll sind Lernen Sie es und teilen Sie es von Zeit zu Zeit mit allen. Ich hoffe, es wird Ihnen helfen.

Dieses Mal beginnen wir mit der grundlegendsten Wartung des WeChat-Applet-Anmeldestatus. Das offizielle API-Dokument des Miniprogramms enthält eine vollständige Erläuterung des Anmeldestatus und des relevanten Codes. Wenn Sie Details sehen möchten, können Sie rausgehen und rechts abbiegen: https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject Ich habe zunächst nicht viel verstanden Als ich es mir einmal ansah, wurde der Code nicht bereitgestellt. Es gibt keine Java-Version, was einem Java-Programmierer peinlich ist. Nach intensiver Recherche habe ich beschlossen, eine einfache Demo der Java-Version zu erstellen und diese zu veröffentlichen.

Wenn Sie als Server die Mitgliedsinformationen mithilfe des WeChat-Applets erhalten möchten, benötigen Sie das Applet als Client, um die grundlegenden Informationen des Mitglieds weiterzugeben. Ähnlich wie eine Mobiltelefonnummer kann openId im aktuellen Miniprogramm als eindeutige Kennung für den Benutzer verwendet werden. Wenn jedoch der Klartext der openId-Informationen des Mitglieds direkt zwischen dem Server und dem Applet hin und her übertragen wird, treten Sicherheitsprobleme auf. Wenn jemand anderes diese openId erhält, entspricht dies dem Abrufen der Mobiltelefonnummer des Mitglieds, und Sie können einige andere Vorgänge ausführen, was offensichtlich unsicher ist.

Um dieses Problem zu lösen, hat WeChat eine relativ sichere Methode eingeführt.

//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)
    }
   }
  });
 }
})

Das WeChat-Applet ruft die API von wx.login auf und Sie erhalten dann einen Code, der für Außenstehende keine Bedeutung hat Senden Sie es mit Zuversicht an den Server. Nachdem der Server den Code erhalten hat, fügen Sie die App-ID und das App-Geheimnis hinzu, die Sie bei der Beantragung des Miniprogramms zum Anpassen der WeChat-Schnittstelle verwendet haben

https://api.weixin.qq.com/sns/jscode2session?appid= APPID&secret= SECRET&js_code=JSCODE&grant_type=authorization_code

Sie können die folgenden Parameter erhalten:

  • Eindeutige OpenID-Benutzerkennung

  • session_key Sitzungsschlüssel

  • unionid Dieses Feld wird nur zurückgegeben, wenn bestimmte Bedingungen erfüllt sind

wobei openid das eindeutige Tag des Mitglieds ist und Zu diesem Zeitpunkt kann das Dienstende gespeichert werden.

session_key wird später beim Entschlüsseln der UnionId (der eindeutigen Kennung des gesamten Mitglieds der offenen Plattform) nützlich sein.

Nachdem der Server die OpenID erhalten hat, muss diese für nachfolgende Interaktionen gespeichert werden. Im Allgemeinen gibt es zwei Möglichkeiten: Eine besteht darin, direkt in die Datenbank einzutreten, und die andere darin, einen effizienteren Cache zu verwenden. Das Poster verwendet Letzteres und verwendet Redis.

Gemäß dem Vorschlag von WeChat müssen Sie einen eindeutigen Wert als eindeutige Kennung von openId generieren. Hier wird die UUID von Java verwendet. Verwenden Sie dann diesen UUID-Wert als Schlüssel, openid und den session_key, der später als Wert verwendet wird, und speichern Sie ihn in Redis. Und geben Sie den UUID-Wert an das Applet zurück. Auf diese Weise kann das Applet den UUID-Wert direkt für die Interaktion mit dem Server verwenden.

Einige Leute fragen sich vielleicht: Wenn jemand den UUID-Wert erhält, unterscheidet sich das nicht vom Erhalt des OpenID-Werts. Er entspricht der eindeutigen Kennung des Mitglieds.

Hier müssen wir also diesen UUID-Wert verarbeiten. Erstens muss die Speicherung in Redis zeitnah erfolgen. Der Sitzungsschlüssel ist 30 Tage lang auf dem WeChat-Server gültig. Es wird empfohlen, den Sitzungsschlüssel nicht länger als 30 Tage zwischenzuspeichern. Wenn der vom Applet übergebene UUID-Wert abläuft, wird er als abgelaufene UUID betrachtet und der Schritt wx.login wird wiederholt.

Zur Vereinfachung von Redis gibt es nicht nur die entsprechende Beziehung zwischen UUID und OpenID. Ein weiterer Datensatz der openid, der der uuid entspricht, wird gespeichert. Der Zweck besteht darin, die vorherige alte uuid basierend auf der openid beim nächsten Mal zu finden. Wenn sie vorhanden ist, löschen Sie sie, fragen Sie dann einen neuen uuid-Wert ab und geben Sie sie ein entsprechende openid Dieser Datensatz wird ebenfalls aktualisiert. Auf diese Weise gibt es keine redundanten schmutzigen Daten auf dem Redis-Server, wodurch die Belastung des Servers verringert wird.

Das Obige ist, was ich über den gesamten Anmeldevorgang verstehe. Natürlich wurde wx.checkSession nicht erwähnt. Wenn Sie feststellen, dass session_key ungültig ist, führen Sie einfach den obigen Vorgang durch. Deshalb habe ich es nicht im Detail gesagt. Ich weiß nicht, ob ich es klar ausgedrückt habe. Ich werde den Schlüsselcode des gesamten Prozesses als Referenz veröffentlichen.

@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);
          }

        }
      }
    }
  }

Ich bevorzuge Jfinal als Projekt-Framework, ein Java-Lightweight-Rapid-Development-Framework. Es ist sehr effizient und wird jedem empfohlen. Sollte es zu Lücken kommen, können Sie gerne aktiv Kommentare und Kritik einbringen.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.

Verwandte Empfehlungen:

Über den Anmeldevorgang des WeChat Mini-Programms

Einführung in die Xiaodouban-Bücher des WeChat Mini-Programms

Das obige ist der detaillierte Inhalt vonJava implementiert die Aufrechterhaltung des Anmeldestatus des WeChat-Applets. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn