Maison  >  Article  >  Applet WeChat  >  Java implémente la maintenance de l'état de connexion de l'applet WeChat

Java implémente la maintenance de l'état de connexion de l'applet WeChat

不言
不言original
2018-06-23 13:39:442806parcourir

Cet article présente principalement l'exemple de code Java pour implémenter la maintenance de l'état de connexion de l'applet WeChat. Il a une certaine valeur de référence. Ceux qui sont intéressés peuvent en apprendre davantage

Je crois que beaucoup d'amis qui aiment déjà le développement. Connaissez WeChat. Quels types d'espèces sont les mini-programmes ? L'affiche originale a commencé à s'intéresser aux mini-programmes pendant la période de test interne et a également écrit plusieurs mini-programmes WeChat qui ont été lancés. Mais fondamentalement, ils sont écrits uniquement sur le front-end. Récemment, l'affiche a écrit un petit projet de programme complet du back-end au front-end, et a rencontré quelques problèmes dans le processus. L'affiche trouvera certains points qu'il juge utiles. apprendre et les partager avec tout le monde de temps en temps, j'espère que cela vous sera utile.

Cette fois, commençons par la maintenance la plus élémentaire de l’état de connexion de l’applet WeChat. Le document API officiel du mini-programme contient une explication complète de l'état de connexion et du code correspondant. Si vous voulez voir les détails, vous pouvez sortir et tourner à droite : https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject Je n'ai pas beaucoup compris le premier La fois où je l'ai regardé, et le code Il n'y a pas de version Java fournie, ce qui met un programmeur Java dans l'embarras, donc après de longues recherches, j'ai décidé de faire une simple démo de la version Java et de la publier.

En tant que serveur, si vous souhaitez obtenir les informations du membre à l'aide de l'applet WeChat, vous avez besoin de l'applet en tant que client pour transmettre les informations de base du membre. Semblable à un numéro de téléphone mobile, openId peut être utilisé comme identifiant unique pour l'utilisateur dans le mini-programme actuel. Cependant, si le texte clair des informations openId du membre est directement transmis entre le serveur et l'applet, il y aura des problèmes de sécurité. Si quelqu'un d'autre obtient cet openId, cela équivaut à obtenir le numéro de téléphone portable du membre, et vous pouvez effectuer d'autres opérations, ce qui est évidemment dangereux.

Afin de résoudre ce problème, WeChat a adopté une méthode relativement sûre.

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

L'applet WeChat appellera l'API de wx.login et obtiendra ensuite un code. Ce code n'a aucune signification pour les étrangers, vous pouvez le faire en toute sécurité. transmettez-le au serveur. Une fois que le serveur a obtenu le code, ajoutez l'appId et le secret d'application que vous avez utilisés lors de la candidature au mini-programme pour ajuster l'interface WeChat

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

Vous pouvez obtenir les paramètres suivants :

  • identifiant unique de l'utilisateur openid

  • session_key clé de session

  • unionid Ce champ ne reviendra que si certaines conditions sont remplies

où openid est la balise unique du membre, et à ce moment, la fin du service peut être enregistrée.

session_key sera utile plus tard lors du décryptage de l'unionId (l'identifiant unique de l'ensemble du membre de la plateforme ouverte).

Une fois que le serveur a obtenu l'openid, il doit être enregistré pour les interactions ultérieures. D'une manière générale, il existe deux manières : l'une consiste à accéder directement à la base de données et l'autre consiste à utiliser un cache plus efficace. L'affiche utilise ce dernier, en utilisant Redis.

Selon la suggestion de WeChat, vous devez générer une valeur unique comme identifiant unique d'openId. L'uuid de Java est utilisé ici. Utilisez ensuite cette valeur uuid comme clé, openid et session_key qui sera utilisée plus tard comme valeur, et stockez-la dans redis. Et renvoyez la valeur uuid à l'applet. De cette façon, l'applet peut utiliser directement la valeur uuid pour interagir avec le serveur.

Certaines personnes peuvent demander, si quelqu'un obtient la valeur uuid, ce n'est pas différent d'obtenir la valeur openid. C'est équivalent à l'identifiant unique du membre.

Nous devons donc ici traiter cette valeur uuid. Tout d'abord, cela doit être opportun lors du stockage dans Redis. La clé de session est valide pendant 30 jours sur le serveur WeChat. Il est recommandé que le serveur mette en cache la clé de session pendant 30 jours maximum. Lorsque la valeur uuid transmise par l'applet expire, elle est considérée comme un uuid expiré et l'étape wx.login est répétée.

Pour la commodité de Redis, il n'y a pas seulement la relation correspondante entre uuid et openid. Un autre enregistrement d'openid correspondant à uuid sera enregistré. Le but est de trouver l'ancien uuid précédent basé sur openid lors de l'étape de re-wx.login la prochaine fois. S'il existe, supprimez-le, puis interrogez une nouvelle valeur d'uuid et mettez la. openid correspondant Cet enregistrement est également mis à jour. De cette façon, il n'y aura pas de données sales redondantes sur le serveur Redis, ce qui réduira la charge sur le serveur.

Ce qui précède est ce que je comprends de l'ensemble du processus de connexion. Bien sûr, wx.checkSession n'a pas été mentionné. En fait, si vous constatez que session_key n'est pas valide, recommencez le processus ci-dessus. Je ne l'ai donc pas dit en détail. Je ne sais pas si j'ai été clair. Je publierai le code clé de l'ensemble du processus pour votre référence.

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

        }
      }
    }
  }

Je préfère Jfinal, un framework léger de développement rapide pour Java, très efficace et recommandé à tout le monde. S'il y a des omissions, vous êtes invités à formuler activement des commentaires et des critiques.

Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !

Recommandations associées :

À propos du processus de connexion du mini-programme WeChat

Introduction aux livres Xiaodouban du mini-programme WeChat

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn