@@ -1,16 +1,14 @@ | |||
package com.iformall.service.toutiao.api; | |||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | |||
import com.google.gson.JsonObject; | |||
import com.iformall.service.toutiao.api.bean.TtOpenAuthorizationInfo; | |||
import com.iformall.service.toutiao.api.bean.TtOpenTicket; | |||
import com.iformall.service.toutiao.api.bean.TtOpenNotifyMsg; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
import me.chanjar.weixin.open.api.WxOpenConfigStorage; | |||
import me.chanjar.weixin.open.bean.WxOpenCreateResult; | |||
import me.chanjar.weixin.open.bean.WxOpenGetResult; | |||
import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate; | |||
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; | |||
import me.chanjar.weixin.open.bean.result.*; | |||
import java.util.List; | |||
@@ -86,7 +84,7 @@ public interface TtOpenComponentService { | |||
boolean checkSignature(String timestamp, String nonce, String encrypt, String signature); | |||
TtOpenTicket decrypt(String encrypt); | |||
TtOpenNotifyMsg decrypt(String encrypt); | |||
String getComponentAccessToken(boolean forceRefresh) throws WxErrorException; | |||
@@ -104,7 +102,7 @@ public interface TtOpenComponentService { | |||
String getPreAuthUrl(String redirectUri) throws WxErrorException; | |||
String route(TtOpenTicket openTicket) throws WxErrorException; | |||
String route(TtOpenNotifyMsg openTicket) throws WxErrorException; | |||
/** | |||
* 使用授权码换取公众号或小程序的接口调用凭据和授权信息. | |||
@@ -11,7 +11,7 @@ public class TtOpenGsonBuilder { | |||
static { | |||
INSTANCE.disableHtmlEscaping(); | |||
INSTANCE.registerTypeAdapter(TtOpenTicket.class, new TtOpenTicketGsonAdapter()); | |||
INSTANCE.registerTypeAdapter(TtOpenNotifyMsg.class, new TtOpenNotifyMsgGsonAdapter()); | |||
INSTANCE.registerTypeAdapter(TtOpenAuthorizationInfo.class, new TtOpenAuthorizationInfoGsonAdapter()); | |||
INSTANCE.registerTypeAdapter(TtOpenRetrieveCode.class, new TtOpenRetrieveCodeGsonAdapter()); | |||
@@ -0,0 +1,56 @@ | |||
package com.iformall.service.toutiao.api.bean; | |||
import lombok.*; | |||
import java.io.Serializable; | |||
/** | |||
* @author S | |||
*/ | |||
@Getter | |||
@Setter | |||
@NoArgsConstructor | |||
@AllArgsConstructor | |||
@Builder | |||
public class TtOpenNotifyMsg implements Serializable { | |||
private static final long serialVersionUID = -44544979421396117L; | |||
private String componentAppId; | |||
/** | |||
* Ticket-----推送ticket | |||
* | |||
*/ | |||
private String msgType; | |||
/** | |||
* PUSH ----- 目前推送ticket | |||
* AUTHORIZED ------ 授权通知 | |||
* UNAUTHORIZED ----- 解除授权通知 | |||
* UPDATE_AUTHORIZED ------- 找回授权码通知 | |||
*/ | |||
private String event; | |||
//------推送ticket | |||
private String ticket; | |||
private String fromUserName; | |||
//2019-01-14 12:45:10 | |||
private String createTime; | |||
//-----授权/解除授权通知/找回授权码 | |||
private String appId;//授权小程序的appid | |||
private String tpAppId;//第三方应用appid | |||
private String eventTime;//授权/解除授权时间 2019-01-14 12:45:10 | |||
private String authorizationCode;//授权码 | |||
private Integer authorizationCodeExpiresIn;//授权码有效期 | |||
public static TtOpenNotifyMsg fromJson(String json) { | |||
return TtOpenGsonBuilder.create().fromJson(json, TtOpenNotifyMsg.class); | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
package com.iformall.service.toutiao.api.bean; | |||
import com.google.gson.*; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import java.lang.reflect.Type; | |||
/** | |||
* . | |||
* | |||
* @author S | |||
*/ | |||
public class TtOpenNotifyMsgGsonAdapter implements JsonDeserializer<TtOpenNotifyMsg> { | |||
@Override | |||
public TtOpenNotifyMsg deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||
return convertFromJson(json.getAsJsonObject()); | |||
} | |||
protected TtOpenNotifyMsg convertFromJson(JsonObject json) { | |||
TtOpenNotifyMsg openTicket = new TtOpenNotifyMsg(); | |||
openTicket.setTicket(GsonHelper.getString(json,"Ticket")); | |||
openTicket.setFromUserName(GsonHelper.getString(json,"FromUserName")); | |||
openTicket.setCreateTime(GsonHelper.getString(json,"CreateTime")); | |||
openTicket.setMsgType(GsonHelper.getString(json,"MsgType")); | |||
openTicket.setEvent(GsonHelper.getString(json,"Event")); | |||
openTicket.setAppId(GsonHelper.getString(json,"AppId")); | |||
openTicket.setTpAppId(GsonHelper.getString(json,"TpAppId")); | |||
openTicket.setEventTime(GsonHelper.getString(json,"EventTime")); | |||
openTicket.setAuthorizationCode(GsonHelper.getString(json,"AuthorizationCode")); | |||
openTicket.setAuthorizationCodeExpiresIn(GsonHelper.getInteger(json,"AuthorizationCodeExpiresIn")); | |||
return openTicket; | |||
} | |||
} |
@@ -1,40 +0,0 @@ | |||
package com.iformall.service.toutiao.api.bean; | |||
import com.iformall.service.toutiao.miniapp.bean.TtMaGsonBuilder; | |||
import lombok.*; | |||
import java.io.Serializable; | |||
/** | |||
* @author S | |||
*/ | |||
@Getter | |||
@Setter | |||
@NoArgsConstructor | |||
@AllArgsConstructor | |||
@Builder | |||
public class TtOpenTicket implements Serializable { | |||
private static final long serialVersionUID = -44544979421396117L; | |||
private String accessToken; | |||
private String ticket; | |||
private String fromUserName; | |||
//2019-01-14 12:45:10 | |||
private String createTime; | |||
private String msgType; | |||
private String event; | |||
private String componentAppId; | |||
public static TtOpenTicket fromJson(String json) { | |||
return TtOpenGsonBuilder.create().fromJson(json, TtOpenTicket.class); | |||
} | |||
} |
@@ -1,34 +0,0 @@ | |||
package com.iformall.service.toutiao.api.bean; | |||
import com.google.gson.*; | |||
import com.iformall.service.toutiao.miniapp.bean.TtMaSubscribeMessage; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import java.lang.reflect.Type; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
/** | |||
* . | |||
* | |||
* @author S | |||
*/ | |||
public class TtOpenTicketGsonAdapter implements JsonDeserializer<TtOpenTicket> { | |||
@Override | |||
public TtOpenTicket deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||
return convertFromJson(json.getAsJsonObject()); | |||
} | |||
protected TtOpenTicket convertFromJson(JsonObject json) { | |||
TtOpenTicket openTicket = new TtOpenTicket(); | |||
openTicket.setTicket(GsonHelper.getString(json,"Ticket")); | |||
openTicket.setFromUserName(GsonHelper.getString(json,"FromUserName")); | |||
openTicket.setCreateTime(GsonHelper.getString(json,"CreateTime")); | |||
openTicket.setMsgType(GsonHelper.getString(json,"MsgType")); | |||
openTicket.setEvent(GsonHelper.getString(json,"Event")); | |||
return openTicket; | |||
} | |||
} |
@@ -10,21 +10,16 @@ import com.iformall.service.toutiao.api.TtOpenService; | |||
import com.iformall.service.toutiao.api.bean.TtOpenAuthorizationInfo; | |||
import com.iformall.service.toutiao.api.bean.TtOpenGsonBuilder; | |||
import com.iformall.service.toutiao.api.bean.TtOpenRetrieveCode; | |||
import com.iformall.service.toutiao.api.bean.TtOpenTicket; | |||
import com.iformall.service.toutiao.api.bean.TtOpenNotifyMsg; | |||
import com.iformall.service.toutiao.utils.MsgDecrypt; | |||
import com.iformall.service.toutiao.utils.ServerVerification; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.common.util.http.URIUtil; | |||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
import me.chanjar.weixin.open.api.WxOpenConfigStorage; | |||
import me.chanjar.weixin.open.bean.*; | |||
import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; | |||
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; | |||
import me.chanjar.weixin.open.bean.result.*; | |||
import me.chanjar.weixin.open.util.WxOpenCryptUtil; | |||
import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.slf4j.Logger; | |||
@@ -97,12 +92,12 @@ public class TtOpenComponentServiceImpl implements TtOpenComponentService { | |||
} | |||
@Override | |||
public TtOpenTicket decrypt(String encrypt) { | |||
public TtOpenNotifyMsg decrypt(String encrypt) { | |||
try { | |||
MsgDecrypt msgDecrypt = new MsgDecrypt(getWxOpenConfigStorage().getComponentAesKey()); | |||
String plainText = msgDecrypt.decrypt(encrypt); | |||
log.info("解密信息----------------------------------------"+ plainText); | |||
TtOpenTicket openTicket = TtOpenTicket.fromJson(plainText); | |||
TtOpenNotifyMsg openTicket = TtOpenNotifyMsg.fromJson(plainText); | |||
openTicket.setComponentAppId(getWxOpenConfigStorage().getComponentAppId()); | |||
return openTicket; | |||
} catch (Exception e) { | |||
@@ -212,12 +207,12 @@ public class TtOpenComponentServiceImpl implements TtOpenComponentService { | |||
@Override | |||
public String route(final TtOpenTicket ticket) throws WxErrorException { | |||
public String route(final TtOpenNotifyMsg ticket) throws WxErrorException { | |||
if (ticket == null) { | |||
throw new NullPointerException("message is empty"); | |||
} | |||
log.info("ticket.getMsgType()"+ticket.getMsgType()); | |||
if (StringUtils.equalsIgnoreCase(ticket.getMsgType(), "Ticket")) { | |||
if (StringUtils.isNotBlank(ticket.getMsgType()) && StringUtils.equalsIgnoreCase(ticket.getMsgType(), "Ticket")) { | |||
getWxOpenConfigStorage().setComponentVerifyTicket(ticket.getTicket()); | |||
return "success"; | |||
} | |||
@@ -1,5 +1,6 @@ | |||
package com.iformall.controller; | |||
import com.iformall.common.Result; | |||
import com.iformall.common.ResultData; | |||
import com.iformall.domain.po.WxAuthorizerInfo; | |||
import com.iformall.domain.vo.WxWeappInfo; | |||
@@ -11,6 +12,7 @@ import com.iformall.service.toutiao.api.bean.TtOpenAuthorizationInfo; | |||
import io.swagger.annotations.Api; | |||
import io.swagger.annotations.ApiOperation; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
@@ -69,7 +71,7 @@ public class TtAuthController { | |||
@ApiOperation(value = "授权", notes = "") | |||
@GetMapping("/jump") | |||
@ResponseBody | |||
public void jump(@RequestParam("auth_code") String authorizationCode) { | |||
public void jump(@RequestParam("authorization_code") String authorizationCode, @RequestParam("expires_in") Integer expiresIn) { | |||
try { | |||
TtOpenAuthorizationInfo queryAuthResult = openService.getTtOpenComponentService().getQueryAuth(authorizationCode); | |||
logger.info("getQueryAuth", queryAuthResult); | |||
@@ -96,36 +98,51 @@ public class TtAuthController { | |||
@ApiOperation(value = "刷新", notes = "") | |||
@GetMapping("/retrieve") | |||
@ResponseBody | |||
public ResultData retrieve() { | |||
WxWeappInfo weappInfo = new WxWeappInfo(); | |||
weappInfo.setPlat(EnumAppPlat.TOUTIAO.getCode()); | |||
List<WxWeappInfo> list = authorizerInfoService.getList(weappInfo); | |||
if(list != null && list.size() > 0){ | |||
for (WxWeappInfo info: list) { | |||
try { | |||
String code = openService.getTtOpenComponentService().retrieveCode(info.getAuthorizerAppid()); | |||
TtOpenAuthorizationInfo queryAuthResult = openService.getTtOpenComponentService().getQueryAuth(code); | |||
logger.info("getQueryAuth", queryAuthResult); | |||
// save auth info | |||
authorizerInfoService.saveOrUpdate(new WxAuthorizerInfo(){ | |||
{ | |||
setAuthorizerAppid(queryAuthResult.getAuthorizerAppid()); | |||
setRefreshToken(queryAuthResult.getAuthorizerRefreshToken()); | |||
setAccessToken(queryAuthResult.getAuthorizerAccessToken()); | |||
setAccessTokenExpire(new Date(Long.valueOf(System.currentTimeMillis() + queryAuthResult.getExpiresIn()*1000))); | |||
setAuthorizationStatus(EnumWxAuthorizationStatus.AUTHORIZED.getCode()); | |||
setAuthTime(new Date()); | |||
} | |||
}); | |||
} catch (WxErrorException e) { | |||
logger.error(info.getAuthorizerAppid()+"找回授权码", e); | |||
throw new RuntimeException(e); | |||
public ResultData retrieve(@RequestParam("appId") String appId) { | |||
if(StringUtils.isNotBlank(appId)){ | |||
try { | |||
retrieveAuthorizerInfo(appId); | |||
}catch(Exception e){ | |||
return new ResultData(Result.ERROR, e.getMessage()); | |||
} | |||
}else{ | |||
WxWeappInfo weappInfo = new WxWeappInfo(); | |||
weappInfo.setPlat(EnumAppPlat.TOUTIAO.getCode()); | |||
List<WxWeappInfo> list = authorizerInfoService.getList(weappInfo); | |||
if(list != null && list.size() > 0){ | |||
for (WxWeappInfo info: list) { | |||
try { | |||
retrieveAuthorizerInfo(info.getAuthorizerAppid()); | |||
}catch(Exception e){ | |||
} | |||
} | |||
} | |||
} | |||
return new ResultData(); | |||
} | |||
private void retrieveAuthorizerInfo(String appid){ | |||
try { | |||
String code = openService.getTtOpenComponentService().retrieveCode(appid); | |||
TtOpenAuthorizationInfo queryAuthResult = openService.getTtOpenComponentService().getQueryAuth(code); | |||
logger.info("getQueryAuth", queryAuthResult); | |||
// save auth info | |||
authorizerInfoService.saveOrUpdate(new WxAuthorizerInfo(){ | |||
{ | |||
setAuthorizerAppid(queryAuthResult.getAuthorizerAppid()); | |||
setRefreshToken(queryAuthResult.getAuthorizerRefreshToken()); | |||
setAccessToken(queryAuthResult.getAuthorizerAccessToken()); | |||
setAccessTokenExpire(new Date(Long.valueOf(System.currentTimeMillis() + queryAuthResult.getExpiresIn()*1000))); | |||
setAuthorizationStatus(EnumWxAuthorizationStatus.AUTHORIZED.getCode()); | |||
setAuthTime(new Date()); | |||
} | |||
}); | |||
} catch (WxErrorException e) { | |||
logger.error(appid+"找回授权码error", e); | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
} |
@@ -1,30 +1,15 @@ | |||
package com.iformall.controller; | |||
import com.google.gson.Gson; | |||
import com.google.gson.GsonBuilder; | |||
import com.iformall.common.Result; | |||
import com.iformall.common.ResultData; | |||
import com.iformall.controller.base.BaseController; | |||
import com.iformall.domain.po.WxAuthorizerInfo; | |||
import com.iformall.domain.po.WxComponentVerifyTicket; | |||
import com.iformall.enums.EnumWxAuthorizationStatus; | |||
import com.iformall.service.WxAuthorizerInfoService; | |||
import com.iformall.service.WxComponentVerifyTicketService; | |||
import com.iformall.service.toutiao.FmTtOpenService; | |||
import com.iformall.service.toutiao.api.bean.TtOpenTicket; | |||
import com.iformall.service.toutiao.api.bean.TtOpenNotifyMsg; | |||
import com.iformall.utils.DateUtils; | |||
import io.swagger.annotations.Api; | |||
import io.swagger.annotations.ApiOperation; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
import me.chanjar.weixin.open.bean.WxOpenCreateResult; | |||
import me.chanjar.weixin.open.bean.WxOpenGetResult; | |||
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; | |||
import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; | |||
import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerListResult; | |||
import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
@@ -34,11 +19,8 @@ import org.springframework.web.bind.annotation.*; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.PrintWriter; | |||
import java.nio.charset.Charset; | |||
import java.util.Date; | |||
import java.util.Map; | |||
@@ -73,7 +55,7 @@ public class TtCalllbackController extends BaseController { | |||
throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); | |||
} | |||
// aes加密的消息, 解密 | |||
TtOpenTicket openTicket = openService.getTtOpenComponentService().decrypt(encrypt); | |||
TtOpenNotifyMsg openTicket = openService.getTtOpenComponentService().decrypt(encrypt); | |||
// 处理 | |||
handleTicket(openTicket); | |||
return "success"; | |||
@@ -84,14 +66,15 @@ public class TtCalllbackController extends BaseController { | |||
* @param | |||
* @return | |||
*/ | |||
private void handleTicket(TtOpenTicket ticket) { | |||
private void handleTicket(TtOpenNotifyMsg ticket) { | |||
try { | |||
String out = openService.getTtOpenComponentService().route(ticket); | |||
this.logger.info("组装回复信息:{}", out); | |||
} catch (WxErrorException e) { | |||
this.logger.error("notify", e); | |||
} | |||
if (StringUtils.equalsIgnoreCase(ticket.getMsgType(), "Ticket")) { | |||
if (StringUtils.isNotBlank(ticket.getMsgType()) && StringUtils.equalsIgnoreCase(ticket.getMsgType(), "Ticket")) { | |||
logger.info("------------推送ticket通知"); | |||
// 保存component_verify_ticket | |||
componentVerifyTicketService.saveOrUpdate(new WxComponentVerifyTicket() { | |||
{ | |||
@@ -101,6 +84,17 @@ public class TtCalllbackController extends BaseController { | |||
setDeadline(new Date(Long.valueOf(System.currentTimeMillis() + (60 * 60 * 1000)))); | |||
} | |||
}); | |||
}else if(StringUtils.isNotBlank(ticket.getEvent()) && StringUtils.equalsIgnoreCase(ticket.getEvent(), "AUTHORIZED")){ | |||
logger.info("------------授权成功通知"); | |||
}else if(StringUtils.isNotBlank(ticket.getEvent()) && StringUtils.equalsIgnoreCase(ticket.getEvent(), "UNAUTHORIZED")){ | |||
logger.info("------------解除授权成功通知"); | |||
}else if(StringUtils.isNotBlank(ticket.getEvent()) && StringUtils.equalsIgnoreCase(ticket.getEvent(), "UPDATE_AUTHORIZED")){ | |||
logger.info("------------找回授权码通知"); | |||
}else{ | |||
logger.info("------------未知通知"); | |||
} | |||
} | |||