背景:最近公司業務與微信公眾號有關,面向微信接口開發
原文地址: https://blog.csdn.net/rongxiang111/article/details/78765514
1.開發語言使用Java
2.使用微信接口測試賬號進行本地測試
3.使用natapp(原ngrok)將本地地址映射到外網地址實現微信公眾號的本地調試
申請微信公眾平台接口測試賬號
打開上面的鏈接地址后,直接用自己的微信掃一下就可以直接登錄了。
登錄成功后,如下顯示:

公網配置前的准備
在我們本地測試的時候,需要將我們的本地地址映射到公網,我們使用一個免費且非常方便的工具:natapp。下面的地址是natapp的官網和natapp的使用教程:
natapp官網
NATAPP 1分鍾快速新手圖文教程
大家可以根據上面的教程來一步步做,我下面還會重新介紹一遍(因為在我跟着官網的教程做的時候后來因為自己的原因遇到了一些小問題)。
免費隧道配置
先注冊,注冊成功后登錄。


注意上圖:本地端口必須是要填8080的(這個購買后也是可以再修改的),因為微信公眾平台接口的調用僅支持80。開發之間建議閱讀微信公眾平台技術文檔。
隧道購買成功后,在我的隧道中就可以看到已擁有的隧道:
客戶端下載
我們訪問到natapp的客戶端下載,下載natapp客戶端:

下載后,解壓,會有一個natapp.exe的文件。
運行natapp
在運行natapp之前需要先配置,詳細教程參考:使用本地配置文件config.ini。config.ini內容:

在這兩個文件的目錄下,打開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,不然是找不到公網映射的。
這樣我們的微信本地開發調試環境就配好了。
前提:需要申請認證的微信公眾號;獲取對應的APPID和APPSECRET;並且還需要獲取到用戶信息權限(點擊“修改“添加服務器的域名地址),前期工作安裝測試賬號為例給大家展示下:
1)、公眾測試賬號獲取
訪問上面的連接,選擇“接口測試號申請”獲得直接打開http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index通過微信客戶端掃碼登錄即可登錄。
登錄完即可獲取到一個測試公眾賬號的信息。主要有appId和appsecret兩個參數,這將唯一標示一個公眾號,並且需要將他們作為參數獲取用戶的信息。

2)、關注公眾號
用戶只有關注了這個公眾號了,才能通過打開有公眾號信息的鏈接去授權第三方登錄,並獲取用戶信息的操作。故我們還需要用我們的微信關注微信號,操作如下:
還是剛剛那個登錄成功后跳轉的頁面,我們可以看到,該頁面有一個二維碼,我們可以通過掃描該二維碼進行關注,關注成功在右邊的“用戶列表”會多一個用戶的信息。如下圖所示:

3)配置回調函數
我們在微信客戶端訪問第三方網頁(即我們自己的網頁)的時候,我們可以通過微信網頁授權機制,我們不僅要有前面獲取到的appid和appsecret還需要有當用戶授權之后,回調的域名設置,即用戶授權后,頁面會跳轉到哪里。具體的配置如下:
還是在剛剛的頁面,有一個“網頁授權獲取用戶基本信息”,點擊后面的修改

填寫回調的域名:

如果你的網址沒有被列入過黑名單,就會在頂部出現

然后,域名配置就成功了!可以進行開發了。
一。授權開發的流程(詳情的東西請以官網為准,在此就不多說了):具體而言,網頁授權流程分為四步:
1、引導用戶進入授權頁面同意授權,獲取code
2、通過code換取網頁授權access_token(與基礎支持中的access_token不同)
3、如果需要,開發者可以刷新網頁授權access_token,避免過期
4、通過網頁授權access_token和openid獲取用戶基本信息(支持UnionID機制)
二.按照如上流程我就不多說廢話直接粘代碼供大家參考,請大家多多指教(代碼里的所有APPID,APPSECRET都是使用的官網提供測試賬號)
1.設計一個公用網絡請求工具類:
WXAuthUtil.java
import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; public class WXAuthUtil { public static final String APPID = "************"; public static final String APPSECRET = "*************"; public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException { JSONObject jsonObject = null; DefaultHttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); HttpResponse response = client.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { // 把返回的結果轉換為JSON對象 String result = EntityUtils.toString(entity, "UTF-8"); jsonObject = JSON.parseObject(result); } return jsonObject; } }
2.微信登錄的實現類(里面包含引導action和確認登錄后的回調函數):
WXLoginController.java
import java.io.IOException; import java.net.URLEncoder; import java.text.ParseException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.alibaba.fastjson.JSONObject; import test.util.WXAuthUtil; @Controller @RequestMapping("/wx") public class WXLoginController { private static final Logger logger = Logger.getLogger(WXLoginController.class); @Autowired private HttpServletRequest request; @Autowired private HttpServletResponse response; /** * 公眾號微信登錄授權 * * @param request * @param response * @return * @throws ParseException * @parameter */ @RequestMapping(value = "/wxLogin", method = RequestMethod.GET) public String wxLogin() throws ParseException { // 這個url的域名必須要進行再公眾號中進行注冊驗證,這個地址是成功后的回調地址 String backUrl = "http://vs6ck3.natappfree.cc/wx/callBack"; // 第一步:用戶同意授權,獲取code String getCodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WXAuthUtil.APPID + "&redirect_uri=" + URLEncoder.encode(backUrl) + "&response_type=code" + "&scope=snsapi_userinfo" + "&state=STATE#wechat_redirect"; logger.info("獲取code, getCodeUrl=" + getCodeUrl); // response.sendRedirect(url); return "redirect:" + getCodeUrl;// 必須重定向,否則不能成功 } /** * 公眾號微信登錄授權回調函數 * * @param modelMap * @param req * @param resp * @return * @throws ServletException * @throws IOException * @parameter */ @RequestMapping(value = "/callBack", method = RequestMethod.GET) @ResponseBody public String callBack() throws ServletException, IOException { String code = request.getParameter("code"); // 第二步:通過code換取網頁授權access_token String getTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WXAuthUtil.APPID + "&secret=" + WXAuthUtil.APPSECRET + "&code=" + code + "&grant_type=authorization_code"; logger.info("獲取token,getTokenUrl=" + getTokenUrl); JSONObject getTokenJson = WXAuthUtil.doGetJson(getTokenUrl); /* * { "access_token":"ACCESS_TOKEN", "expires_in":7200, * "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } */ logger.info("獲取token,getTokenJson=" + getTokenJson.toJSONString()); String openid = getTokenJson.getString("openid"); String access_token = getTokenJson.getString("access_token"); String refresh_token = getTokenJson.getString("refresh_token"); // 第五步驗證access_token是否失效;展示都不需要 String vlidTokenUrl = "https://api.weixin.qq.com/sns/auth?access_token=" + access_token + "&openid=" + openid; logger.info("驗證token,vlidTokenUrl=" + vlidTokenUrl); JSONObject validTokenJson = WXAuthUtil.doGetJson(vlidTokenUrl); logger.info("驗證token,validTokenJson=" + validTokenJson.toJSONString()); if (!"0".equals(validTokenJson.getString("errcode"))) { // 第三步:刷新access_token(如果需要)-----暫時沒有使用,參考文檔https://mp.weixin.qq.com/wiki, String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + openid + "&grant_type=refresh_token&refresh_token=" + refresh_token; logger.info("刷新token,refreshTokenUrl=" + refreshTokenUrl); JSONObject refreshTokenJson = WXAuthUtil.doGetJson(refreshTokenUrl); /* * { "access_token":"ACCESS_TOKEN", "expires_in":7200, * "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } */ logger.info("刷新token,refreshTokenJson=" + refreshTokenJson.toJSONString()); access_token = refreshTokenJson.getString("access_token"); } // 第四步:拉取用戶信息(需scope為 snsapi_userinfo) String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN"; logger.info("獲取用戶信息,getUserInfoUrl=" + getUserInfoUrl.toString()); JSONObject getUserInfoJson = WXAuthUtil.doGetJson(getUserInfoUrl); /* * { "openid":" OPENID", " nickname": NICKNAME, "sex":"1", "province":"PROVINCE" * "city":"CITY", "country":"COUNTRY", "headimgurl": * "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46", * "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], "unionid": * "o6_bmasdasdsad6_2sgVt7hMZOPfL" } */ logger.info("獲取用戶信息,getUserInfoJson=" + getUserInfoJson.toString()); /* * end 獲取微信用戶基本信息 */ // 獲取到用戶信息后就可以進行重定向,走自己的業務邏輯了。。。。。。 // 接來的邏輯就是你系統邏輯了,請自由發揮 return getUserInfoJson.toString(); } }
祖先原文地址:https://blog.csdn.net/weixin_43031215/article/details/83345388
