微信网页授权
参考文档:微信公众平台—微信网页开发—微信网页授权(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN)
调试插件:微信web开发者工具(下载地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455784140&token=&lang=zh_CN)
请自备微信公众号账密(管理员),如需Eclipse自测还需其他支持。
一、授权支持,可直接跳过
1.网页授权之前,需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。域名为所支持域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头。
2.理解scope。微信公众号平台用snsapi_base为scope网页授权,获取进入页面的用户的openid,是静默授权(没有手动授权页面)并自动跳转到回调页的。以snsapi_userinfo为scope发起的网页授权是手动授权,不适用也不解释。
3.网页授权access_token。在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息,注意这里的access_token和基础支持中获取的access_token意义相同但是两种不一样的参数,最大的区别就是基础支持access_token获取是有限制的,网页授权access_token获取是无限制的。
4.关于UnionID此处用不到。
二、授权操作步骤
1.获取code
在微信公众号菜单中配置网页url:
规范如下:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect。
说明:红色框内为填写项
参数解释参考文档,这里只说具体填法:APPID填写(https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=229619119&lang=zh_CN公众号平台—基本配置—开发者ID)微信唯一标识,REDIRECT_URI填写带域名的网页url(链接中无参数不需urlencode处理,有参数则需处理),SCOPE填写snsapi_base,STATE填写123(也可按照参考文档自行填写,只是一个无关紧要的参数)。其他说明:response_type=code不用填写,是回调参数,#wechat_redirect不用修改是固定格式。
举例:
此时在微信web开发者工具中,调试该url,网页将跳转到:redirect_uri/?code=CODE&state=STATE。说明可以通过后台请求获取该code参数。
举例:
注意:code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
此时可以在后台request请求中拿到code参数值:(本人实测所有代码均在java过滤器方法doFilter()中)
String code = request.getParameter("code");
logger.info(code);
2.使用code调取openid
在官方微信网页授权步骤中,在取得code之后是换取access_token,但如果网页授权的作用域为snsapi_base,则在获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。所以该步骤我们用来调取openid。
说明:红色框内为填写项
APPID同上,secret填写(公众号平台—基本配置—开发者ID)AppSecret应用密钥,code填写上一步骤获取的参数值。
该步骤需要在后台发请求:发请求的代码在工具类WeixinUtil中,方法返回值即为openid。
public class WeixinUtil { private final static Log logger = LogFactory.getLog(WeixinUtil.class); @Value("${weixin.appSecret}") private String appSecret; @Value("${weixin.appid}") private String appid; @Value("${weixin.api.token_byCode}") private String wxApiTokenByCode; //以上为文件application.properties配置项,也可以在代码中直接拼接该url //发出请求,返回参数为openid public String getTicketAndOpenid(String code) { HttpURLConnection conn = null; logger.debug("getOpenid url:" +MessageFormat.format(wxApiTokenByCode,appid,appSecret,code)); try { URL url = new URL(MessageFormat.format(wxApiTokenByCode,appid,appSecret,code)); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5 * 1000); InputStream inStream = conn.getInputStream(); Map<?, ?> m = jsonDecoder.decode(inStream, Map.class); String openid = String.valueOf(m.get("openid")); if (StringUtils.isNotBlank(openid)) { return openid; } } catch (Exception e) { logger.error("获取openid出错", e); } finally { conn.disconnect(); } return null; } }
3.跳转到目标网页
有了openid就可以直接跳转到目标网页。
代码如下:直接用请求转发跳转页面。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String url = httpRequest.getRequestURL().toString();
logger.info("url="+url) String code = request.getParameter("code"); String openId = null; String paramUrlStr = null; if (StringUtils.isNotBlank(code)){ openId=weixinUtil.getTicketAndOpenid(code); paramUrlStr =url+"?openId="+openId; logger.info("paramUrlStr=" + paramUrlStr); httpResponse.sendRedirect(paramUrlStr); return; } }
==================================END========================================================================
浙公网安备 33010602011771号