第一步
先去微信公众平台申请公众号,网址:https://mp.weixin.qq.com/,然后有了公众号申请测试号,拿到appID和appsecret
第二步
申请url和域名
(1) 测试号二维码添加自己的微信号(后期使用微信web开发者工具)可以用自己微信测试,注意
因为微信的授权接口必须是域名不能ip,所有这边没有域名的小伙伴可以使用NATAPP
公网配置前的准备:
在我们本地测试的时候,需要将我们的本地地址映射到公网,我们使用一个免费且非常方便的工具:natapp。下面的地址是natapp的官网和natapp的使用教程:
natapp官网 :https://natapp.cn/
NATAPP 1分钟快速新手图文教程 :https://natapp.cn/article/natapp_newbie
免费隧道配置
先注册,注册成功后登录。
注意上图:本地端口必须是要填8080的(这个购买后也是可以再修改的),因为微信公众平台接口的调用仅支持80。开发之间建议阅读微信公众平台技术文档。
隧道购买成功后,在我的隧道中就可以看到已拥有的隧道:
客户端下载
我们访问到natapp的客户端下载,下载natapp客户端:
下载后,解压,会有一个natapp.exe的文件。
运行natapp
在运行natapp之前需要先配置,详细教程参考:使用本地配置文件config.ini。config.ini内容:
注意:config.ini配置文件需要与natapp.exe在同一个目录下。
在这两个文件的目录下,打开cmd命令窗口,输入:
natapp -authtoken=你的authtoken
回车,运行成功后是如下界面:
- Tunnel Status Online 代表链接成功
- Version 当前客户端版本,如果有新版本,会有提示
- Forwarding 当前穿透 网址 或者端口
- Web Interface 是本地Web管理界面,可在隧道配置打- 开或关闭,仅用于web开发测试
- Total Connections 总连接数
- Avg Conn Time 0.00ms 这里不代表,不代表,不代表 延时,需要注意!
这两个都是可以访问的,区别就是使用natapp是将本地映射到公网上了,别人也可以访问,但是别人就不能访问你的127.0.0.1:8080。注意:用http://xxx.natappfree.cc
访问的时候运行natapp的cmd窗口要开着,也就是得运行着natapp,不然是找不到公网映射的
(2) 申请url,有了域名以后自己写个api直接返回就可以成功了
1 @ApiOperation(value = "微信申请URL")
2 @GetMapping("")
3 public void getUrl(HttpServletRequest request, HttpServletResponse response) throws IOException {
4 log.info("WeiXinController getUrl start");
5
6 Enumeration pNames = request.getParameterNames();
7 String logName = null;
8 while (pNames.hasMoreElements()) {
9 String name = (String) pNames.nextElement();
10 String value = request.getParameter(name);
11 logName = "name =" + name + " value =" + value;
12 }
13 log.info("logName: " + logName);
14
15 // 微信加密签名
16 String signature = request.getParameter("signature");
17 // 时间戳
18 String timestamp = request.getParameter("timestamp");
19 // 随机数
20 String nonce = request.getParameter("nonce");
21 // 随机字符串
22 String echostr = request.getParameter("echostr");
23 PrintWriter out = response.getWriter();
24 out.print(echostr);
25 out.close();
26 String info = "signature = " + signature + ", timestamp = " + timestamp + ", nonce = " + nonce + ", echostr = "+ echostr;
27 log.info(info);
28
29 log.info("WeiXinController getUrl end");
30 }
第三步
后台接口测试
第一个servlet:
@Slf4j
@WebServlet(name = "weChatLoginServlet", urlPatterns = "/wechat/login")
public class WeiXinLoginServlet extends HttpServlet {
public WeiXinLoginServlet() {
super();
}
/**
* 微信公众号唯一标识(在微信小程序管理后台获取)
*/
@Value("${wechat.appId}")
private String appId;
/**
* 回调地址
*/
@Value("${wechat.backUrl}")
private String backUrl;
/**
* 第一步:引导用户进入授权页面同意授权,获取code
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
log.debug("WeiXinLoginServlet doGet start");
// 授权页面地址
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"
+ "appid=" + appId
+ "&redirect_uri=" + urlEncodeUTF8(backUrl)
+ "&response_type=code"
+ "&scope=snsapi_base"
+ "&state=STATE#wechat_redirect";
// 重定向到授权页面
response.sendRedirect(url);
log.debug("WeiXinLoginServlet doGet end");
}
/**
* 用 urlEncode 对链接进行处理
*
* @author
* @date 2019-03-19
*/
private String urlEncodeUTF8(String source) {
log.debug("WeiXinLoginServlet urlEncodeUTF8 start, source = [{}]", source);
String result = source;
try {
result = java.net.URLEncoder.encode(source,"utf-8");
} catch (UnsupportedEncodingException e) {
log.info("WeiXinController urlEncodeUTF8 BaseException: " + e.getMessage());
}
log.debug("WeiXinLoginServlet urlEncodeUTF8 end");
return result;
}
}
第二个servlet:
@Slf4j
@WebServlet(name = "weChatCallbackServlet", urlPatterns = "/wechat/callback")
public class WeiXinCallBackServlet extends HttpServlet {
public WeiXinCallBackServlet() {
super();
}
/**
* 微信公众号唯一标识(在微信小程序管理后台获取)
*/
@Value("${wechat.appId}")
private String appId;
/**
* 回调地址
*/
@Value("${wechat.secret}")
private String secret;
/**
* 第二步:通过code换取网页授权openid
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
log.debug("WeiXinCallBackServlet callback start");
// 从request里面获取code参数(当微信服务器访问回调地址的时候,会把code参数传递过来)
String code = request.getParameter("code");
// 获取code后,请求以下链接获取access_token
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
+ "appid=" + appId
+ "&secret=" + secret
+ "&code=" + code
+ "&grant_type=authorization_code";
// 通过网络请求方法来请求上面这个接口
JSONObject jsonObject = doGetJson(url);
// 从返回的JSON数据中取出access_token和openid,拉取用户信息时用
// String token = jsonObject.getString("access_token");
String openid = jsonObject.getString("openid");
// 第四步:拉取用户信息(需scope为 snsapi_userinfo)
// String infoUrl ="https://api.weixin.qq.com/sns/userinfo?"
// + "access_token=" + token
// + "&openid=" + openid
// + "&lang=zh_CN";
// 通过网络请求方法来请求上面这个接口
// JSONObject userInfo = doGetJson(infoUrl);
request.setAttribute("openid", openid);
// request.getRequestDispatcher("/login?channel=1&source=1&openid=" + openid).forward(request, response);
log.debug("WeiXinCallBackServlet callback end");
}
/**
* 工具类
* @param url String
* @return JSONObject
*/
private JSONObject doGetJson(String url) throws IOException {
log.debug("WeiXinCallBackServlet doGetJson start, url = [{}]", url);
JSONObject jsonObject = null;
// 首先初始化HttpClient对象
HttpClient client = HttpClientBuilder.create().build();
// 通过get方式进行提交
HttpGet httpGet = new HttpGet(url);
// 通过HTTPclient的execute方法进行发送请求
HttpResponse response = client.execute(httpGet);
// 从response里面拿自己想要的结果
HttpEntity entity = response.getEntity();
if(entity != null){
String result = EntityUtils.toString(entity,"UTF-8");
jsonObject = JSONObject.parseObject(result);
}
// 把链接释放掉
httpGet.releaseConnection();
log.debug("WeiXinCallBackServlet doGetJson end");
return jsonObject;
}
访问第一个servlet以后会得到一个跳转地址,然后直接在微信web开发者工具上使用就可以测试获取openId了