微信小程序注册登录
配置微信公众测试号
https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=279116570 进入配置页面
2.配置接口配置信息
token随便找个生成的就行
URL内网穿透的生成的加上你写的签名接口地址进行验证绑定
@RestController
@RequestMapping("/wx/portal")
public class WxPortalController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private WxConfig wxConfig;
@Autowired
private WxMpMessageRouterConfig wxMpMessageRouterConfig;
private static final String ENC_TYPE_AES = "aes";
/**
* 用来进行微信认证,也就是当在:
* 公众号官方管理后台->开发->基本配置->修改配置 时,需要进行的校验
*
* @return
*/
@GetMapping(produces = "text/plain;charset=utf-8")
public String authGet(@RequestParam(name = "signature", required = false) String signature,
@RequestParam(name = "timestamp", required = false) String timestamp,
@RequestParam(name = "nonce", required = false) String nonce,
@RequestParam(name = "echostr", required = false) String echostr) {
this.logger.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature,
timestamp, nonce, echostr);
if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
// 请求参数非法,请核实
throw new IllegalArgumentException("yami.sys.illegalArgument");
}
if (wxConfig.getWxMpService().checkSignature(timestamp, nonce, signature)) {
return echostr;
}
return echostr;
}
/**
* 接收公众号的消息
*
* @return
*/
@PostMapping(produces = "application/xml; charset=UTF-8")
public String post(@RequestBody String requestBody,
@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam("openid") String openid,
@RequestParam(name = "encrypt_type", required = false) String encType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) {
this.logger.info("\n接收微信请求:[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}],"
+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
String out = null;
if (encType == null) {
// 明文传输的消息
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
WxMpXmlOutMessage outMessage = this.route(inMessage);
if (outMessage == null) {
return "";
}
out = outMessage.toXml();
} else if (ENC_TYPE_AES.equalsIgnoreCase(encType)) {
// aes加密的消息
WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxConfig.getWxMpService().getWxMpConfigStorage(),
timestamp, nonce, msgSignature);
this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString());
WxMpXmlOutMessage outMessage = this.route(inMessage);
if (outMessage == null) {
return "";
}
out = outMessage.toEncryptedXml(wxConfig.getWxMpService().getWxMpConfigStorage());
}
this.logger.debug("\n组装回复信息:{}", out);
return out;
}
private WxMpXmlOutMessage route(WxMpXmlMessage message) {
try {
return wxMpMessageRouterConfig.getMessageRouter().route(message);
} catch (Exception e) {
this.logger.error("路由消息时出现异常!", e);
}
return null;
}
/**
* 生成二维码
*
* @return url
* @throws WxErrorException
*/
@GetMapping("/create")
public String create() {
try {
WxMpQrcodeService qrcodeService = wxConfig.getWxMpService().getQrcodeService();
// 获取二维码ticket
WxMpQrCodeTicket wxMpQrCodeTicket = qrcodeService.qrCodeCreateTmpTicket(Constant.SCENEID, 10000);
String url = qrcodeService.qrCodePictureUrl(wxMpQrCodeTicket.getTicket(), true);
return url;
} catch (WxErrorException e) {
e.printStackTrace();
}
return null;
}
/**
* 用于检测扫码和关注状态
*
* @return
*/
@PostMapping("/checkLogin")
public String checkLogin(@RequestBody JSONObject ticketJson) {
String ticket = ticketJson.get("ticket").toString();
logger.info("ticket---->" + ticket);
String openId = null;
//如果redis中有ticket凭证则说明用户已扫码说明登陆成功
if (RedisUtil.hasKey(ticket)) {
openId = RedisUtil.get(ticket).toString();
logger.info("openId---->" + openId);
//扫码通过则删除
RedisUtil.del(ticket);
}
return openId;
}
/**
* 根据openID获取用户信息
*
* @param openId
* @return
*/
@GetMapping("/getUserInfo")
public WxMpUser getUserInfo(String openId) {
WxMpUserService userService = wxConfig.getWxMpService().getUserService();
try {
WxMpUser user = userService.userInfo(openId);
return user;
} catch (WxErrorException e) {
e.printStackTrace();
}
return null;
}
}
/**
* 微信路由的配置
* @author LGH
*/
@Component
@AllArgsConstructor
public class WxMpMessageRouterConfig {
private final MenuHandler menuHandler;
private final MsgHandler msgHandler;
private final SubscribeHandler subscribeHandler;
private final ScanHandler scanHandler;
private final WxConfig wxConfig;
public WxMpMessageRouter getMessageRouter() {
WxMpMessageRouter newRouter = new WxMpMessageRouter(wxConfig.getWxMpService());
// 自定义菜单事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.MenuButtonType.CLICK).handler(this.menuHandler).end();
// 关注事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.SUBSCRIBE).handler(this.subscribeHandler)
.end();
// 扫码时已经关注过的事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.SCAN).handler(this.scanHandler).end();
// 默认
newRouter.rule().async(false).handler(this.msgHandler).end();
return newRouter;
}
}
@Component
public class SubscribeHandler extends AbstractHandler {
private final WeixinSubscribeService weixinSubscribeService;
@Autowired
public SubscribeHandler(WeixinSubscribeService weixinSubscribeService) {
this.weixinSubscribeService = weixinSubscribeService;
}
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService weixinService,
WxSessionManager sessionManager) throws WxErrorException {
this.logger.info("新关注用户 OPENID: " + wxMessage.getFromUser());
// 关注时推送的消息
String openid = wxMessage.getFromUser();
logger.info("WxMpXmlOutMessage.openId-->SubscribeHandler"+openid);
// 将ticket 存储进redis 用这个属性来通知前端该用户已经关注了。
String ticket = wxMessage.getTicket();
RedisUtil.set(ticket,openid,10000);
logger.info("WxMpXmlOutMessage.ticket-->SubscribeHandler"+ticket);
List<WeixinSubscribe> weixinSubscribes = weixinSubscribeService.listWeixinSubscribeAndMaterial();
WxMpKefuService kefuService = weixinService.getKefuService();
for (WeixinSubscribe weixinSubscribe : weixinSubscribes) {
String msgType = weixinSubscribe.getMsgType();
WxMpKefuMessage kefuMessage = new WxMpKefuMessage();
kefuMessage.setToUser(openid);
kefuMessage.setMsgType(msgType);
if (WxConsts.KefuMsgType.TEXT.equals(msgType)) {
kefuMessage.setContent(weixinSubscribe.getContent());
} else if (WxConsts.KefuMsgType.NEWS.equals(msgType)) {
WxMpNewsArticle article = Json.parseObject(weixinSubscribe.getContent(), WxMpNewsArticle.class);
WxMpKefuMessage.WxArticle wxArticle = new WxMpKefuMessage.WxArticle();
wxArticle.setDescription(article.getDigest());
wxArticle.setPicUrl(article.getThumbUrl());
wxArticle.setTitle(article.getTitle());
wxArticle.setUrl(article.getUrl());
kefuMessage.setArticles(Collections.singletonList(wxArticle));
} else {
kefuMessage.setMediaId(weixinSubscribe.getMediaId());
}
kefuService.sendKefuMessage(kefuMessage);
}
return null;
}
}
3.接口安全域名修改
4.网页账号配置回调地址
5.使用natapp或者其他内网穿透工具生成一个随机域名(自行查找)