微信授權登入_程式碼可以直接使用
阿新 • • 發佈:2019-02-20
微信網頁授權登陸,官方文件:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
直接上程式碼,相關注意事項在程式碼中已用TODO標記
Controller層
package com.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.service.WXService; /** * 微信授權登入流程 * 1,建立授權URL * 2,使用者授權 * 3,微信回撥 * 4,自身業務處理 */ public class WXController { private WXService wXService; // 微信Service /** * 建立授權登入URL * * @return * @throws Exception */ public String createAuthenUrl() throws Exception { return wXService.createAuthorizationURL(); } /** * 獲取授權認證 * * @param request * @param response */ public void getAuthorization(HttpServletRequest request, HttpServletResponse response) { // 獲取微信授權端返回的code String code = request.getParameter("code"); // 獲取微信授權端返回的status String state = request.getParameter("state"); // TODO 自身業務邏輯 } /** * 頁面輪詢 * * @param request * @return */ public String checkedState(HttpServletRequest request) { String state = request.getParameter("state"); // TODO 自身業務邏輯 return ""; } }
Service層
package com.service; import java.util.UUID; import com.send.SendHttpRequest; public class WXService { // 公眾號的唯一標識 private static String APP_ID = ""; // 公眾號的APPSecret private static String APP_SECRET = ""; // 使用者同意授權URL(對urlEncode之後) private static String REDIRECT_URL = ""; // 使用者同意授權URL private static String AUTHORIZATION_URL = "https://open.weixin.qq.com/connect/oauth2/authorize"; // 獲取access_tokenURL private static String GET_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token"; // 拉取使用者資訊URL private static String GET_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo"; /** * 獲取微信普通的token用於呼叫微信一般的介面 * * @return * @throws Exception */ public String getCommonToken() throws Exception { // 獲取token的url String url = "https://api.weixin.qq.com/cgi-bin/token"; // 引數 String param = "grant_type=client_credential&appid=" + APP_ID + "&secret=" + APP_SECRET; // 傳送請求並獲取資訊 String result = SendHttpRequest.sendGetRequest(url, param); // 校驗是否請求成功 if (result == null) { throw new Exception("獲取token失敗"); } if (result.contains("errcode")) { throw new Exception(result); } // TODO 返回值資訊參照官方文件 // TODO 返回值中的token需要儲存在本地,token過期後再獲取.注意:本地的過期時間要早於微信返回的過期時間 return result; } /** * 建立授權登入URL * * 1,獲取普通token * 2,生成微信使用者登入授權URL * 3,將長連結轉成短連結(這步可以省略,但不建議。原因:長連結生成的二維碼非常密集,導致效能較差的手機,掃碼時間過長或者無法識別) * 4,返回state和short_url * * @return * @throws Exception */ public String createAuthorizationURL() throws Exception { // 普通token String commontoken = ""; // state(根據業務需求而定,這裡用於頁面輪詢) String state = UUID.randomUUID().toString().replace("-", ""); // 微信使用者登入授權URL String longUrl = AUTHORIZATION_URL +"?appid=" + APP_ID + "&redirect_uri=" + REDIRECT_URL + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect"; // 請求路徑(將長連結轉成短連結) String url = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=" + commontoken; // 請求引數 String param = "{" + "\"action\":\"long2short\"," + "\"long_url\":\"" + longUrl +"\"" + "}"; // TODO 返回值資訊參照官方文件 // 傳送請求並獲取結果(將長連結轉成短連結) String result = SendHttpRequest.sendPostRequest(url, param); if (!result.contains("short_url")) { throw new Exception(result); } // TODO 根據業務需求儲存state和state過期時間(微信回撥時會返回該引數;頁面輪詢時,需要校對state) // TODO 在result中獲取short_url String short_url = ""; String resultMap = "{" + "\"state\":" + "\"" + state +"\"," + "\"shortURL\":" + "\"" + short_url + "\"" + "}"; return resultMap; } /** * 用code換取access_token相關資訊 * * @param code 用於換取access_token * @return * @throws Exception */ public String getAccessToken(String code) throws Exception { // 建立請求引數 String param = "appid=" + APP_ID +"&secret=" + APP_SECRET + "&code=" + code + "&grant_type=authorization_code"; // 傳送請求並獲取響應資訊 String result = SendHttpRequest.sendGetRequest(GET_TOKEN_URL, param); // 校驗是否請求成功 if (result == null) { throw new Exception("獲取token失敗"); } if (result.contains("errcode")) { throw new Exception(result); } // TODO 返回值資訊參照官方文件 return result; } /** * 用accessToken和openid拉取使用者資訊 * * @param accessToken * @param openid * @return * @throws Exception */ public String getUserInfo(String accessToken, String openid) throws Exception { // 建立請求引數 String param = "access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN "; // 傳送請求並獲取響應資訊 String result = SendHttpRequest.sendGetRequest(GET_USER_INFO_URL, param); // 校驗是否請求成功 if (result == null) { throw new Exception("獲取userInfo失敗"); } if (result.contains("errcode")) { throw new Exception(result); } // TODO 返回值資訊參照官方文件 return result; } }
SendHttpRequest類
package com.send; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; /** * 傳送http請求 * */ public class SendHttpRequest { /** * 傳送GET請求 * * @param url 請求地址 * @param param 請求引數(格式:key1=value1&key2=value2&key3=value3) * @return * @throws Exception */ public static String sendGetRequest(String url, String param) throws Exception { String result = ""; BufferedReader in = null; try { // 拼接URL和引數 String urlAndParam = url + "?" + param; // 建立URL物件 URL realUrl = new URL(urlAndParam); // 開啟URL的連結 URLConnection conn = realUrl.openConnection(); // 設定Head資訊 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); // 建立連結 conn.connect(); // 定義 BufferedReader輸入流來讀取URL的響應 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); // 臨時引數 String line; // 獲取響應結果 while ((line = in.readLine()) != null) { result += line; } }catch(Exception e) { throw new Exception("請求失敗"); }finally { try { if (in != null) { in.close(); } } catch (Exception e2) { throw new Exception("請求失敗"); } } return result; } /** * 傳送POST請求 * * @param url 請求地址 * @param param 請求引數[格式:key1=value1&key2=value2 || JSON.toString()] * @return * @throws Exception */ public static String sendPostRequest(String url, String param) throws Exception { String result = ""; PrintWriter out = null; BufferedReader in = null; try { // 建立URL物件 URL realUrl = new URL(url); // 開啟URL的連結 URLConnection conn = realUrl.openConnection(); // 設定Head資訊 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); // POST請求設定 conn.setDoOutput(true); conn.setDoInput(true); // 獲取輸出流 out = new PrintWriter(conn.getOutputStream()); // 傳送請求引數 out.print(param); // flush輸出流的緩衝 out.flush(); // 獲取輸入流,讀取響應請求 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); // 臨時引數 String line; // 獲取響應結果 while ((line = in.readLine()) != null) { result += line; } }catch(Exception e) { throw new Exception("請求失敗"); }finally { try { if (in != null) { in.close(); } } catch (Exception e2) { throw new Exception("請求失敗"); } } return result; } public static void main(String[] args) throws Exception { System.out.println(sendPostRequest("http://www.baidu.com", "")); } }
寫的不嚴謹的地方,請指出哈!先謝謝指教