一、问题场景

  开发模式的微信服务号开通用户身份绑定功能,将微信用户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需要转码后替换) */
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect;

2.获取网页内授权凭证

/** 获取网页内授权凭证(APPID、SECRET、CODE需要替换) */
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code;

3. 发送https请求,Get方法