項目中咱們常常會遇到第三方登陸,那咱們今天就來看看WX公衆號受權登陸的過程是怎麼樣的,其實微信公衆平臺中的開發者文檔已經寫得很是清晰了,不過我今天仍是總結一下,方便之後須要時能夠直接拉過去用;java
微信公衆平臺: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842web
固然既然是公衆號,那你就須要一個測試號; 這個測試帳號哪裏來,就百度好了;apache
有測試號的能夠在這查看公衆號信息:json
https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/indexapi
好了,就來看代碼吧:微信
新建一個web項目:app
須要引入的jar包:微信公衆平臺
commons-beanutils-1.9.3.jar commons-collections-3.2.2.jar commons-lang-2.6.jar commons-logging-1.2.jar ezmorph-1.0.6.jar fluent-hc-4.5.3.jar httpclient-4.5.3.jar httpcore-4.4.6.jar json-lib-2.4-jdk15.jar
1, 新建配置文件:ide
package wx.config; public class WxConfig { public static final String APPID = "wxb6ad5296120ddc1e"; public static final String APPSECRET = "4a69dcc6af046e00b1d9ec523afe5f48"; /** * 回調地址 */ private static final String REDIRECT_URI = "http://gy.tunnel.qydev.com/myWebTest/wxCallback"; /** * 獲取微信受權地址 * */ public static String getWXLoginUrl(){ //微信受權地址,必須在微信中拿到 String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + "appid="+APPID + "&redirect_uri="+REDIRECT_URI + "&response_type=code" + "&scope=snsapi_userinfo" + "&state=STATE#wechat_redirect"; //開發者文檔上說要用 urlEncode對回調地址進行處理,但我處理後,就報域名不一致的錯誤,不處理反而訪問成功,因此這兒是個坑,應該多注意; return url; } public static void main(String[] args) { System.out.println(getWXLoginUrl()); } }
2, HTTP請求工具:工具
package common; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.http.client.fluent.Request; import org.apache.http.client.fluent.Response; import net.sf.json.JSONObject; /** * <p>類說明:微信請求工具 * <p>建立人:geYang * <p>建立時間:2017.08.29 * */ public class HttpUtil { /** * <p>方法說明: HTTP GET 請求 * <p>編碼格式: UTF8 * <p>參數說明: String urL 請求的路徑 * <p>返回說明: JSONObject * */ public static JSONObject doGet(String url) throws Exception{ Request request = Request.Get(url); request.setHeader("Content-type", "application/json;charset=UTF8"); Response response = request.execute(); String jsonData = response.returnContent().asString(); String string = new String(jsonData.getBytes("ISO-8859-1"),"UTF-8"); JSONObject json = JSONObject.fromObject(string); return json; } /** *<p>方法說明: 獲取請求參數 *<p>返回說明: Map<String,String> receiveMap *<p>建立時間: 2017年11月3日 下午2:25:02 *<p>創 建 人: geYang * @throws UnsupportedEncodingException **/ public static Map<String,String> getReceiveMap(HttpServletRequest request) throws UnsupportedEncodingException{ Map<String,String> receiveMap = new HashMap<String,String>(); Map<String, String[]> requestParams = request.getParameterMap(); for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = iter.next(); String[] values = requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //亂碼解決,這段代碼在出現亂碼時使用 // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8"); receiveMap.put(name, valueStr); } return receiveMap; } }
3,建立回調接口: 這裏的接口與上面配置文件中的回調地址必須保持一致;
package wx.servlet; import java.io.IOException; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import common.HttpUtil; import net.sf.json.JSONObject; import wx.config.WxConfig; /** * 微信登陸回調 */ @WebServlet("/wxCallback") public class CallbackServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("微信回調到了"); String code = request.getParameter("code"); Map<String, String> receiveMap = HttpUtil.getReceiveMap(request); System.out.println(receiveMap); //經過 code 換取受權 access_token //URL: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + "appid="+WxConfig.APPID + "&secret="+WxConfig.APPSECRET + "&code="+code + "&grant_type=authorization_code"; try { JSONObject json = HttpUtil.doGet(url); Object openid = json.get("openid"); Object access_token = json.get("access_token"); if(openid!=null){ System.out.printf("openid: %s;\naccess_token: %s;\n",openid,access_token); } //經過access_token拉取用戶信息 //URL: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN String userInforUrl = "https://api.weixin.qq.com/sns/userinfo?" + "access_token="+access_token + "&openid="+openid + "&lang=zh_CN"; JSONObject jsonUser = HttpUtil.doGet(userInforUrl); Object nickname = jsonUser.get("nickname"); Object sex = jsonUser.get("sex"); Object headimgurl = jsonUser.get("headimgurl"); if(nickname!=null){ System.out.printf("暱稱 : %s; 性別: %s; 圖像: %s\n",nickname,sex,headimgurl); } response.setContentType("application/json;charset=utf-8"); // response.setCharacterEncoding("UTF-8"); response.getWriter().append("暱稱: "+nickname+"<br/>").append("性別: "+sex+"<br/>").append("圖像:<img src='"+headimgurl+"'/>"); } catch (Exception e) { e.printStackTrace(); } } }
好了,只要拿到用戶的openid,那麼咱們就能夠根據本身的須要來看是否獲取用戶信息,若是咱們有本身的帳號體系,徹底能夠不須要其餘信息,只同過openid的綁定就能夠了.
注意:
1, 回調地址必須是外網能夠訪問的域名,不能爲ip,咱們能夠利用 ngrok 或者 花生殼 來映射域名;
2, 公衆號管理中的網頁受權必須與咱們回調地址的域名一致,不然會報域名不一致的錯誤;