微信公众号开发-微信网页授权获取用户openid

文档链接:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

首先需要到微信公众号进行一些设置,这里以测试公众号为例进行说明。

首先到如下链接申请一个测试公众号:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login,直接用微信扫一下码即可注册成功,简单快捷!

申请好测试公众号之后,登录到后台进行管理,如下所示:

注意如下参数(参数列表):

1.appID:微信公众号应用id

2.appsecret:微信公众号应用秘钥

3.URL:进行接入开发的url

4.token:令牌,类似于密码

5.JS安全域名:一种安全设置,调用微信JS-SDK的时候,域名必须符合这里的设置

6.授权回调域名:授权步骤中,微信需要回调你的接口,这个接口的域名就是在这里设置的。

以上参数中,3到6都是需要各位亲自己去设置的哦!

---------------------------------------------------- 分隔符 ----------------------------------------------------

好了,进行这些设置后,让我们进入开发吧,但是开发之前,需要进行接入操作,也就是说,你得让微信公众号服务器去验证你的服务器所在的url地址和域名等信息。(经过实测,这个接入操作是可以省略的)

首先开发一个http接口(以java代码为例,后面都是用java来说明的):

/**
	 * 验证开发者,确认请求来自微信服务器
	 * 
	 * @param signature
	 * @param timestamp
	 * @param nonce
	 * @param echostr
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value="/access", method=RequestMethod.GET)
	public void wxAccess(String signature, String timestamp, String nonce, String echostr,
			HttpServletResponse response) throws IOException {
		
		try {
			response.setHeader("Content-type", "text/html;charset=UTF-8");
			response.setCharacterEncoding("utf-8");
			PrintWriter out = response.getWriter();
			if (signature == null) {
				out.write("参数错误!");
			}
			boolean result = SignUtil.validSign(signature, WeixinConstant.TOKEN, timestamp, nonce);   //WeixinConstant.TOKEN即参数列表中的"4.token:令牌,类似于密码"
			if (result) {
				out.write(echostr);
				System.out.println("验证完成");
			} else {
				out.write("验证失败!");
			}
			out.flush();
		    out.close(); 
		} catch (Exception e) {
			e.printStackTrace();
		}
       
		System.out.println("完成操作!");
	}
public class SignUtil {
	public static boolean validSign(String signature, String tocken, String timestamp, String nonce) {
		String[] paramArr = new String[] { tocken, timestamp, nonce };
		Arrays.sort(paramArr);
		StringBuilder sb = new StringBuilder(paramArr[0]);
		sb.append(paramArr[1]).append(paramArr[2]);
		String ciphertext = null;
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			byte[] digest = md.digest(sb.toString().getBytes());
			ciphertext = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	
		return ciphertext != null ? ciphertext.equals(signature.toUpperCase()) : false;
	}

	private static String byteToStr(byte[] byteArray) {
		String rst = "";
		for (int i = 0; i < byteArray.length; i++) {
			rst += byteToHex(byteArray[i]);
		}
		return rst;
	}
	
	private static String byteToHex(byte b) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(b >>> 4) & 0X0F];
		tempArr[1] = Digit[b & 0X0F];
		String s = new String(tempArr);
		return s;
	}

}

注意,这个接口必须支持get方式的请求,因为微信发出接入请求是通过get方式进行的。还有就是这个接口的url要对应上面参数列表中的"3.URL:进行接入开发的url"

好了,接入完毕之后,我们开始写授权的接口。

/**
	 * 用户授权
	 * @param request
	 * @param response
	 */
	@RequestMapping("/auth")
	public String auth(HttpServletRequest request, HttpServletResponse response) {
				
		try {
			
			String redirectURL = "";
			redirectURL = Constant.ENTRANCE_URL;   //Constant.ENTRANCE_URL即下文中的回调接口
			
			String pageURL = request.getParameter("pageURL");   //pageURL即用户需要去的页面url,在授权完毕后会重定向到该页面
			redirectURL += "?pageURL=" + pageURL;
			
			/*String params = request.getQueryString();
			if(StringUtils.isNotBlank(params)) {
				redirectURL += "?" + params;
			}*/
			
			String redirectURL_encode = java.net.URLEncoder.encode(redirectURL, WeixinConstant.CHARSET);
			
			String authURL = WeixinConstant.CODE_AUTH_URL.replace("APPID", WeixinConstant.APPID)
								.replace("REDIRECT_URI", redirectURL_encode)
								.replace("SCOPE", WeixinConstant.SCOPE_BASE)
								.replace("STATE", WeixinConstant.STATE);
			
			//System.out.println(authURL);
			return "redirect:" + authURL;
		} catch (Exception e) {
			log.error("授权失败", e);			
		}
		
		return "redirect:" + Constant.INDEX_URL;
	}

 这里贴出WeixinConstant类的代码:

/**
 * @author mawj
 * @date 2017年6月21日 上午8:52:48
 * 微信配置文件
 */
public class WeixinConstant {

	private WeixinConstant() {
		
	}
	
	//微信号
	public static final String WEIXINCODE;
	
	//appID
	public static final String APPID;
	
	//appsecret
	public static final String APPSECRET;
	
	//token
	public static final String TOKEN;
	
	//charset
	public static final String CHARSET;
	
	//授权类型
	public static final String SCOPE_BASE = "snsapi_base";
	
	//授权STATE
	public static final String STATE = "123";
	
	//access_token的key
	public static final String ACCESS_TOKEN = "access_token";
	
	//jsapi_ticket的key
	public static final String JSAPI_TICKET = "jsapi_ticket";
	
	//授权URL,获取code
	public static String CODE_AUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
	
	//授权URL,获取access_token和openid
	public static String TOKEN_AUTH_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	
	//获取access_token
	public static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	
	//获取jsapi_ticket
	public static String JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	
	//发送模板消息url
	public static String SEND_TEMPLATE_MSG_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
	
	//发送消息通路url
	public static String SEND_MSG_PATH_URL = "https://api.weixin.qq.com/cityservice/sendmsgdata?access_token=ACCESS_TOKEN";
	
	//创建公众号菜单
	public static String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";

	static {
		WEIXINCODE = WeixinPropertyManager.getProperty("weixincode");
		APPID = WeixinPropertyManager.getProperty("appID");
		APPSECRET = WeixinPropertyManager.getProperty("appsecret");
		TOKEN = WeixinPropertyManager.getProperty("token");
		CHARSET = WeixinPropertyManager.getProperty("charset");
	}
	
}

接下来要开发回调接口,在微信公众号服务器执行完授权步骤之后,会重定向到该地址:

/**
	 * 回调地址
	 * @param request
	 * @param response
	 */
	@RequestMapping("/entrance")
	public String entrance(HttpServletRequest request, HttpServletResponse response) {
		
		String pageURL = "";
		
		try {
			
			String code = request.getParameter("code");
			pageURL = request.getParameter("pageURL");
			
			String json_result = "";
			
			if(StringUtils.isNotBlank(code)) {
				String authURL = WeixinConstant.TOKEN_AUTH_URL.replace("APPID", WeixinConstant.APPID)
									  .replace("SECRET", WeixinConstant.APPSECRET)
									  .replace("CODE", code);
				json_result = HttpUtil.doGet(authURL);
			}
			
			//System.out.println(">>>>>" + json_result);
			
			if(StringUtils.isNotBlank(json_result)) {
				JSONObject obj_result = JSONObject.fromObject(json_result);
				String openid = obj_result.optString("openid");
				System.out.println("用户授权成功:" + openid);
				if(StringUtils.isNotBlank(openid)) {
					request.getSession().setAttribute(WeixinConstant.SESSION_OPEN_ID, openid);
				}
			}
			
		} catch (Exception e) {
			log.error("授权出错", e);
		}
		
		if(pageURL == null || pageURL.equals("") || pageURL.equals("null") || pageURL.equals("NULL")) {
			return "redirect:" + Constant.INDEX_URL;
		}
		return "redirect:" + pageURL;
	}

其中,HttpUtil.doGet()的使用可以参考我这篇博文:https://blog.csdn.net/qq9808/article/details/78320816

在处理完授权的逻辑之后,就可以重定向到用户真正要去的那个页面了。

开发完毕后,授权入口格式如下所示:

http://ip:port/auth?pageURL=http://www.baidu.com

猜你喜欢

转载自blog.csdn.net/qq9808/article/details/81558926