Utilisez l'agent de plate-forme publique WeChat du serveur nginx écrit en Lua.
Cible:
Utilisez le nginx frontal comme proxy WeChat pour réduire le couplage entre la couche d'application interne et les services WeChat.
Configurez les réponses automatiques pour les comptes publics WeChat et traitez certains messages utilisateur dans nginx pour réduire la pression sur la couche application.
Gestion unifiée du access_token
utilisé dans l'API du compte public WeChat, en tant que serveur de contrôle central pour isoler la couche métier et la mise en œuvre de l'API, réduire access_token
et augmenter la stabilité du service.
Déployez la page de rappel d'autorisation WeChat JS-SDK pour réduire la pression sur la couche d'application.
configuration
Données de configuration globale du compte public, y compris les paramètres de jeton d'interface et de réponse automatique.
serveur
Recevez des demandes de messages ordinaires et de demandes push d'événements de WeChat et répondez selon la configuration. Si aucune configuration correspondante n'est effectuée, success
sera renvoyé conformément aux exigences de WeChat.
Cette partie du code principal est refactorisée et modifiée à partir de aCayF/lua-resty-wechat.
Utilisez config.autoreplyurl
pour configurer l'adresse du service de traitement en arrière-plan, transférer, traiter et répondre aux messages WeChat complexes (dépend de pintsized/lua-resty-http).
proxy_access_token
Utilisez Redis pour mettre en cache access_token
et jsapi_ticket
, appeler automatiquement les mises à jour du service WeChat régulièrement et prendre en charge les mises à jour distribuées.
procuration
L'agent appelle l'interface API de la plateforme publique WeChat et ajoute automatiquement le paramètre access_token
.
proxy_access_filter
Filtrez l’adresse IP du client et limitez les sources de requêtes.
oauth
jssdk_config
Configuration nginx :
http { lua_package_path 'chemin d'accès aux fichiers lua'; résolveur 114.114.114.114; lua_shared_dict wechat 1M; # Utiliser la mémoire partagée pour maintenir une seule minuterie init_by_lua ' ngx.shared.wechat:delete("updater") -- Effacer l'identifiant de la minuterie require( "resty.wechat.config") '; init_worker_by_lua ' local ok, err = ngx.shared.wechat:add("updater", "1") -- Minuteur de démarrage d'un seul processus si ce n'est pas ok ou err, alors renvoie la fin require("resty.wechat.proxy_access_token")() ' ; serveur {emplacement /wechat-server { content_by_lua ' require("resty.wechat.server")() '; }location /wechat-proxy/ { rewrite_by_lua ' require("resty.wechat.proxy") ("wechat-proxy") -- le paramètre est le chemin d'accès'; access_by_lua ' require("resty.wechat.proxy_access_filter")( ) ' ; proxy_pass https://api.weixin.qq.com/; }emplacement /wechat-baseoauth { # param : goto rewrite_by_lua ' require("resty.wechat.oauth").base_oauth("chemin vers /wechat-redirect") '; }emplacement /wechat-userauth { # param : goto rewrite_by_lua ' require("resty.wechat.oauth").userinfo_oauth("chemin vers /wechat-redirect") '; }emplacement /wechat-redirect { rewrite_by_lua ' require("resty.wechat.oauth").redirect() '; }emplacement /wechat-jssdk-config { # GET/POST, param : url, [api] add_header Access-Control-Allow-Origin "si besoin d'un appel inter-domaines" ; content_by_lua ' require("resty.wechat.jssdk_config") ()'; } } }
Autorisations JS-SDK pour l'injection de pages Web :
$.ajax({ url : "chemin d'accès à l'url vers /wechat-jssdk-config", données : {url : window.location.href,api : "onMenuShareTimeline|onMenuShareAppMessage|onMenuShareQQ|onMenuShareWeibo|onMenuShareQZone" }, succès : function(réponse) {wx.config(réponse); }});$.ajax({ url : "chemin d'accès à l'url vers /wechat-jssdk-config", données : {url : window.location.href }, succès : fonction (réponse) {wx.config ({ appId : réponse.appId, horodatage : réponse.timestamp, nonceStr : réponse.nonceStr, signature : réponse.signature, jsApiList : [ 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ' , 'onMenuShareWeibo', 'onMenuShareQZone' ]}); }});
Utiliser Java pour analyser les cookies obtenus par autorisation de page Web proxy
Map authInfo = JSON.parseObject(decryptAES(unBase64("cookie value"), getKey("AES key")));//Clé AES par défaut : "vFrItmxI9ct8JbAg"//Configurée dans config.lua -> cookie_aes_key//Méthode de dépendance importer com.alibaba.fastjson.JSON; importer com.google.common.base.Charsets; importer javax.crypto.Cipher; importer javax.crypto.spec.SecretKeySpec; importer java.security.Key; remplissage public StringBuilder (String s, lettre de caractère, répétitions int) {StringBuilder sb = new StringBuilder(s); while (répète-- > 0) {sb.append(lettre); }retourner qn; }public String padding(String s) {return padding(s, '=', s.length() % 4).toString(); }public byte[] unBase64(String value) {return org.apache.commons.codec.binary.Base64.decodeBase64(padding(value)); }public String string(byte[] octets) {return new String(bytes, Charsets.UTF_8); }public String decryptAES(byte[] value, Key key) {try {Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, key);byte[] déchiffré = chiffre. doFinal(value);return string(déchiffré); } catch (Exception e) {throw new RuntimeException(e); } }public byte[] bytes(String str) {return str == null null : str.getBytes(Charsets.UTF_8); }clé publique keyFromString(String keyString) {return new SecretKeySpec(bytes(keyString), "AES"); }clé publique getKey(String key) {if (key.length() >= 16) {return keyFromString(key.substring(0, 16)); }StringBuilder sb = new StringBuilder(key); while (sb.length() < 16) {sb.append(key); }return keyFromString(sb.toString().substring(0, 16)); }