一、问题场景
开发模式的微信服务号开通用户身份绑定功能,将微信用户openId与输入的身份证号码进行校验绑定。微信用户关注服务号成功后响应图文消息,点击身份绑定跳转到身份绑定页面,输入身份证号码点击查询信息并绑定。
这个场景中身份绑定信息后台无法获取该微信用户的OpenId。想要获取微信用户信息,就需要微信平台回调模式。微信提供了回调模式,这种回调模式的可以将用户发送给微信的信息,转发到用户提供的一个回调接口上,该接口解析用户发送过来的信息,解析后进行相应处理。而且回调模式中,可以调用的东西不少,扫码,图片,视频,地理位置信息等。
二、开启回调模式注意点
1. 必须使用外网能够访问得到的URL(不能是本地服务器)
2. JDK版本必须要1.7以上
3. jec加解密包必须与JDKversion一致
4. 微信企业号开启回调模式默认只支持80或443端口
三、案例代码
1.微信服务号菜单链接__身份绑定请求路径
http://服务器域名/educloud/response/getCode
2. 请求Mapping的Controller
package com.zichen.xhkq.controller.mine;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import net.sf.json.JSONObject;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.zichen.xhkq.pojo.OpenidStatus;
import com.zichen.xhkq.service.mine.BindStatusService;
import com.zichen.xhkq.service.mine.WechatService;
import com.zichen.xhkq.util.Constants;
import com.zichen.xhkq.util.HttpUtil;
import com.zichen.xhkq.util.PropertiesHelper;
@Controller
@RequestMapping("/response")
public class ResponseController {
@Resource
private BindStatusService bindStatusService;
@Resource
private WechatService wechatService;
private static Logger log = LogManager.getLogger(ResponseController.class);
//绑定身份
@RequestMapping("/getCode")
public String getCode(int schoolId){
System.out.println("测试getCode"+schoolId);
String backUri = Constants.REDIRECT_BINDURL.replace("relayDomanName", PropertiesHelper.getRelayDomanName());
String appid = wechatService.selectWechat(schoolId).getAppid();
String url = Constants.NET_AUTHORIZE;
try {
url = url.replace("APPID", appid).replace("REDIRECT_URI", URLEncoder.encode(backUri, "utf-8")).replace("SCOPE", Constants.WXPAY_SCOPE).replace("STATE", Constants.WXPAY_STATE);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
log.info("跳转的页面"+url);
return "redirect:"+url;
}
@RequestMapping("/getOpenid")
public String getOpenid(String code,HttpServletRequest request, HttpServletResponse response,int schoolId){
log.info("网页授权获取/getOpenid");
String appid = wechatService.selectWechat(schoolId).getAppid();
String appsecret = wechatService.selectWechat(schoolId).getAppsecret();
//先网页授权,通过网页授权后获取code参数,通过code参数获取access-token。
String openId = "";
String result = "";
String URL = Constants.NET_ACCESSTOKEN;
URL = URL.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);
log.info("网页授权获取access-token的的链接为"+URL);
JSONObject jsonObject = HttpUtil.httpsRequest(URL, "GET", null);
if (null != jsonObject) {
log.info("调用网页授权接口链接返回的值为"+jsonObject.toString());
HttpSession session = request.getSession();
openId = jsonObject.getString("openid");
session.setAttribute("openId", openId);
List<OpenidStatus> status = bindStatusService.findStatus(openId);
if(status!=null && status.size()>0){
for (int i = 0; i < status.size(); i++) {
if (status.get(i)!=null) {
session.setAttribute("status", status.get(i));
result="hasbind-user";
}
}
}else {
result="bind-user";
}
}
return result;
}
}
3.准备回调路劲Constants.REDIRECT_BINDURL
该路径为调用微信公众平台授权后的回调项目路径
/**绑定身份时的授权回调方法*/
public static final String REDIRECT_BINDURL = "http://relayDomanName/educloud/response/getOpenid";
4. 微信公共平台网页授权请求Constants.NET_AUTHORIZE
/** 网页授权请求(APPID、SCOPE需要替换REDIRECT_URI需要转码后替换) */
public static final String NET_AUTHORIZE = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
5. 替换URL中的参数
url = url.replace("APPID", appid).replace("REDIRECT_URI", URLEncoder.encode(backUri, "utf-8")).replace("SCOPE", Constants.WXPAY_SCOPE).replace("STATE", Constants.WXPAY_STATE);
其中:
(1)APPID 为服务号appid
(2)REDIRECT_URI 为授权后的回调路径,3中已准备好
(3)SCOPE 授权作用域 Constants.WXPAY_SCOPE
/**
* 应用授权作用域,有两种:
* 1、snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),
* 2、snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
*/
public static final String WXPAY_SCOPE = "snsapi_base";
(4)STATE state参数 Constants.WXPAY_STATE
/**重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节*/
public static final String WXPAY_STATE = "ejs";
(5) 重定向URL,向微信平台发送授权请求
return "redirect:"+url;
四、案例解析主要步骤
1.网页授权请求
/** 网页授权请求(APPID、SCOPE需要替换REDIRECT_URI需要转码后替换) */
2.获取网页内授权凭证
/** 获取网页内授权凭证(APPID、SECRET、CODE需要替换) */
3. 发送https请求,Get方法