1.填写授权回调页面域名:
1.1获取微信公众平台测试账号
1.2对帐号进行接口配置填写
1.3填写授权回调页面域名
- 注意域名填写不要加
http://
或者https://
2授权成功获得Openid
- 主要是根据微信公众平台技术文档进行操作。
2.1用户同意授权,获取code
在确保微信公众账号拥有授权作用域
的权限的前提下(服务号获得高级接口后,默认拥有
scope
参数中的snsapi_base
和snsapi_userinfo
),引导关注者打开如下页面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
//若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。
2.1.1封装普通url成授权url
-
本人是采用过滤器的方式封装url引导用户访问上面授权链接:
public class OpenidFilter implements Filter { private static String flag1 = "1"; private static String flag2 = "2"; @Override public void destroy() { } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //转换request 和 respond HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; flag1 = request.getRequestURI(); // 判断是否同一个路径封装成微信的路径再次访问 System.out.println("是否同一个路径封装成微信的路径再次访问" + flag1.equals(flag2)); if (!flag1.equals(flag2)) { // 判断request中是否有openid if (CheckUtil.isNullOrBlank((String) request.getSession().getAttribute("openid"))) { flag2 = request.getRequestURI(); // 修改成微信的url String url = WeixinUtil.AUTHORIZE_URL.replace("APPID", WeixinUtil.APPID) .replace("SCOPE", WeixinUtil.SCOPR) .replace("REDIRECT_URI", WeixinUtil.DOMAIN_NAME + request.getRequestURI()); System.out.println("过滤修改后的url:" + url); //重定向url response.sendRedirect(url); return; } } chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { } }
-
此过滤器应该为一级调用,web.xml配置:
openidFilter com.weixin.oauth.filter.OpenidFilter openidFilter /* 1
-
直接在微信Web开发工具输入需要封装的url:
过滤修改后的url:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9240e5de6afdd7b1&redirect_uri=http://zhixiaoyi.nat300.top/weixinOAuth/OAuthServlet.do&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
2.1.2授权访问获得code
- 之后会进入授权页面:
2.2通过code获得openid
- 在获得code之后需立即采用WeixinUtil通过code换取网页授权access_token。
这里通过code换取的是一个特殊的网页授权
access_token
,与基础支持中的access_token
(该access_token
用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token
。如果网页授权的作用域为snsapi_base
,则本步骤中获取到网页授权access_token
的同时,也获取到了openid
,snsapi_base
式的网页授权流程即到此为止。
获得
access_token
的请求连接:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
其返回JSON数据包如下:
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE" }
-
获得code和openid的servlet:
@WebServlet(name = "OAuthServlet.do", urlPatterns = { "/OAuthServlet.do" }) public class OAuthServlet extends HttpServlet { private static final long serialVersionUID = 1L; public OAuthServlet() { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 得到code String code = request.getParameter("code"); //先检测是否已经得到openid String openid = (String) request.getSession().getAttribute("openid"); if(CheckUtil.isNullOrBlank(openid)){ //判断cede是否为空即是否需要访问获得openid if (!CheckUtil.isNullOrBlank(code)) { System.out.println("code:" + code); //采用WeixinUtil通过code换取网页授权access_token OAuthInfo oauthInfo = WeixinUtil.getAccessToken(WeixinUtil.APPID, WeixinUtil.APPSECRET, code); request.getSession().setAttribute("openid", oauthInfo.getOpenId()); } } request.getRequestDispatcher("index.jsp").forward(request, response); System.out.println("openid:" + openid); } }
WeixinUtil代码如下:
public class WeixinUtil {
// 公众号id
public static String APPID = "wx9240e5de6afdd7b1";
// 公众号密钥
public static String APPSECRET = "2de51d7fae9cb5f36d5468c15bc288fe";
// 用户同意授权url,获取code
public static String AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
// 通过code换取网页授权access_token的url
public static String ACCESS_TOKEN_BY_CODE_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
// 授权域名
public static String DOMAIN_NAME = "http://zhixiaoyi.nat300.top";
// url范围
public static String SCOPR = "snsapi_userinfo";
/**
* Get请求
*
* @param url
* @return
*/
public static JSONObject doGetStr(String url) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
JSONObject jsonObject = null;
try {
HttpResponse httpRequest = httpClient.execute(httpGet);
HttpEntity entity = httpRequest.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSONObject.fromObject(result);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsonObject;
}
/**
* Post请求
*
* @param url
* @param outStr
* @return
*/
public static JSONObject doPostStr(String url, String outStr) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
JSONObject jsonObject = null;
try {
httpPost.setEntity(new StringEntity(outStr, "UTF-8"));
HttpResponse httpRequest = httpClient.execute(httpPost);
HttpEntity entity = httpRequest.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSONObject.fromObject(result);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsonObject;
}
/**
* 网页授权获取openId第2步,根据code取得openId
*
* @param appid
* 公众号的唯一标识
* @param secret
* 公众号的appsecret密钥
* @param code
* code为换取access_token的票据
* @return
*/
/**
*
* 通过code获取access_token
*
* @return
*/
public static OAuthInfo getAccessToken(String appid, String secret, String code) {
OAuthInfo oAuthInfo = new OAuthInfo();
String url = ACCESS_TOKEN_BY_CODE_URL.replace("APPID", appid).replace("SECRET", secret).replace("CODE", code);
JSONObject jsonObject = doGetStr(url);
if (jsonObject != null) {
oAuthInfo.setAccessToken(jsonObject.getString("access_token"));
oAuthInfo.setOpenId(jsonObject.getString("openid"));
oAuthInfo.setExpiresIn(jsonObject.getInt("expires_in"));
oAuthInfo.setRefreshToken(jsonObject.getString("refresh_token"));
oAuthInfo.setScope(jsonObject.getString("scope"));
}
return oAuthInfo;
}
}
-
控制台输出结果:
是否同一个路径封装成微信的路径再次访问false 过滤修改后的url:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9240e5de6afdd7b1&redirect_uri=http://zhixiaoyi.nat300.top/weixinOAuth/OAuthServlet.do&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect 是否同一个路径封装成微信的路径再次访问true code:051FhwC11h9UfM1y5xE11yjBC11FhwC6 openid:ozlH6v1yu2otJOmT1BsD24d25xBU
页面展示openid:
-
用到的pojo:
public class OAuthInfo { // 网页授权接口调用凭证 private String accessToken; // access_token接口调用凭证超时时间 private int expiresIn; // 用户刷新access_token private String refreshToken; // 用户唯一标识 private String openId; // 用户授权的作用域 private String scope; public String getAccessToken() { return accessToken; } public int getExpiresIn() { return expiresIn; } public String getRefreshToken() { return refreshToken; } public String getOpenId() { return openId; } public String getScope() { return scope; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public void setExpiresIn(int expiresIn) { this.expiresIn = expiresIn; } public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } public void setOpenId(String openId) { this.openId = openId; } public void setScope(String scope) { this.scope = scope; } @Override public String toString() { return "OAuthInfo [accessToken=" + accessToken + ", expiresIn=" + expiresIn + ", refreshToken=" + refreshToken + ", openId=" + openId + ", scope=" + scope + "]"; } }