@Override protected void encode(ChannelHandlerContext ctx, WeixinResponse response, List<Object> out) throws WeixinException { WeixinMessageTransfer messageTransfer = ctx.channel().attr(ServerToolkits.MESSAGE_TRANSFER_KEY).get(); EncryptType encryptType = messageTransfer.getEncryptType(); StringBuilder content = new StringBuilder(); content.append("<xml>"); content.append( String.format( "<ToUserName><![CDATA[%s]]></ToUserName>", messageTransfer.getFromUserName())); content.append( String.format( "<FromUserName><![CDATA[%s]]></FromUserName>", messageTransfer.getToUserName())); content.append( String.format( "<CreateTime><![CDATA[%d]]></CreateTime>", System.currentTimeMillis() / 1000l)); content.append(String.format("<MsgType><![CDATA[%s]]></MsgType>", response.getMsgType())); content.append(response.toContent()); content.append("</xml>"); if (encryptType == EncryptType.AES) { AesToken aesToken = messageTransfer.getAesToken(); String nonce = ServerToolkits.generateRandomString(32); String timestamp = Long.toString(System.currentTimeMillis() / 1000l); String encrtypt = MessageUtil.aesEncrypt(aesToken.getWeixinId(), aesToken.getAesKey(), content.toString()); String msgSignature = MessageUtil.signature(aesToken.getToken(), nonce, timestamp, encrtypt); content.delete(0, content.length()); content.append("<xml>"); content.append(String.format("<Nonce><![CDATA[%s]]></Nonce>", nonce)); content.append(String.format("<TimeStamp><![CDATA[%s]]></TimeStamp>", timestamp)); content.append(String.format("<MsgSignature><![CDATA[%s]]></MsgSignature>", msgSignature)); content.append(String.format("<Encrypt><![CDATA[%s]]></Encrypt>", encrtypt)); content.append("</xml>"); } ctx.writeAndFlush( HttpUtil.createHttpResponse( content.toString(), OK, ServerToolkits.CONTENTTYPE$APPLICATION_XML)); logger.info("{} encode weixin response:{}", encryptType, content); }
@Override protected void channelRead0(ChannelHandlerContext ctx, WeixinRequest request) throws WeixinException { final AesToken aesToken = request.getAesToken(); if (aesToken == null || (StringUtil.isBlank(request.getSignature()) && StringUtil.isBlank(request.getMsgSignature()))) { ctx.writeAndFlush(HttpUtil.createHttpResponse(BAD_REQUEST)) .addListener(ChannelFutureListener.CLOSE); return; } /** 公众平台:无论Get,Post都带signature参数,当开启aes模式时带msg_signature参数 企业号:无论Get,Post都带msg_signature参数 */ if (request.getMethod().equals(HttpMethod.GET.name())) { if (!StringUtil.isBlank(request.getSignature()) && MessageUtil.signature(aesToken.getToken(), request.getTimeStamp(), request.getNonce()) .equals(request.getSignature())) { ctx.write(new SingleResponse(request.getEchoStr())); return; } if (!StringUtil.isBlank(request.getMsgSignature()) && MessageUtil.signature( aesToken.getToken(), request.getTimeStamp(), request.getNonce(), request.getEchoStr()) .equals(request.getMsgSignature())) { ctx.write( new SingleResponse( MessageUtil.aesDecrypt(null, aesToken.getAesKey(), request.getEchoStr()))); return; } ctx.writeAndFlush(HttpUtil.createHttpResponse(FORBIDDEN)) .addListener(ChannelFutureListener.CLOSE); return; } else if (request.getMethod().equals(HttpMethod.POST.name())) { if (!StringUtil.isBlank(request.getSignature()) && !MessageUtil.signature(aesToken.getToken(), request.getTimeStamp(), request.getNonce()) .equals(request.getSignature())) { ctx.writeAndFlush(HttpUtil.createHttpResponse(FORBIDDEN)) .addListener(ChannelFutureListener.CLOSE); return; } if (request.getEncryptType() == EncryptType.AES && !MessageUtil.signature( aesToken.getToken(), request.getTimeStamp(), request.getNonce(), request.getEncryptContent()) .equals(request.getMsgSignature())) { ctx.writeAndFlush(HttpUtil.createHttpResponse(FORBIDDEN)) .addListener(ChannelFutureListener.CLOSE); return; } } else { ctx.writeAndFlush(HttpUtil.createHttpResponse(METHOD_NOT_ALLOWED)) .addListener(ChannelFutureListener.CLOSE); return; } WeixinMessageTransfer messageTransfer = MessageTransferHandler.parser(request); ctx.channel().attr(Consts.MESSAGE_TRANSFER_KEY).set(messageTransfer); messageDispatcher.doDispatch(ctx, request, messageTransfer); }