您好,登錄后才能下訂單哦!
這篇文章主要介紹微信開發之如何獲取OAuth2.0網頁授權認證和獲取用戶信息進行關聯,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
最近有做了關于微信公眾號和自己網站用戶進行用戶關聯授權登錄的一個功能,主要是用戶關注該公眾號,點擊會員中心,則會彈出需要關聯授權的網頁授權:OAuth3.0網頁授權,然后用戶同意獲取用戶信息,進行用戶和網站的關聯,然后用戶則可以使用微信進行登錄。
本次做的是一個在Java的Action層處理各個返回參數獲取數據。
一、 使用到的工具:
1、ngrok,將你自己的本機映射到公網,這樣保證可以隨時測試開發;
1、下載ngrok,網址:www.tunnel.mobi/
2、將文件放到Tomcat目錄下,在cmd中運行ngrok -config ngrok.cfg -subdomain xinzhi 8080
3、ngrok工具為在慕課網@LAOBI 看到的
2、微信公眾號測試賬號,隨時測試,首先保證在測試賬號下沒有問題后在進行公眾號的移植。
二、使用到在Java中發送一個Http請求,然后返回JSON參數,獲得JSON參數,然后進行處理。
首先,獲取將公眾號測試號放到properties文件中,以便我們進行調用或者更換,如:url請用https
Properties代碼
AppID = wxf00**c3dd2ebfa0 AppSecret = 3cb220755f****506dc35391aa5c03ec url = https://xinzhi.tunnel.mobi
這里url為我們映射到外網的地址,一會需要用到。然后需要兩個工具類,該工具類作用是在Java的Action中發送http請求后獲取到去返回值
這里使用的是@柳峰,關于服務器請求的代碼http://blog.csdn.net/lyq8479/article/details/9841371,啟用自己有相應的改動,以適應本項目的需求:
WeixinUtil.java 和 MyX509TrustManager.java
Java代碼
package com.zhtx.common.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 公眾平臺通用接口工具類 * * @author xinz * @date 2015-10-14 */ public class WeixinUtil { private static Logger log = LoggerFactory.getLogger(WeixinUtil.class); /** * 發起https請求并獲取結果 * * @param requestUrl 請求地址 * @param requestMethod 請求方式(GET、POST) * @param outputStr 提交的數據 * @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值) */ public static String httpRequest(String requestUrl, String requestMethod, String outputStr) { StringBuffer buffer = new StringBuffer(); try { // 創建SSLContext對象,并使用我們指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 從上述SSLContext對象中得到SSLSocketFactory對象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 設置請求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 當有數據需要提交時 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意編碼格式,防止中文亂碼 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 將返回的輸入流轉換成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 釋放資源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); } catch (ConnectException ce) { log.error("Weixin server connection timed out."); } catch (Exception e) { log.error("https request error:{}", e); } return buffer.toString(); } }
對于https請求,我們需要一個證書信任管理器,這個管理器類需要自己定義,但需要實現X509TrustManager接口,代碼如下:
Java代碼
package com.zhtx.common.util; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; /** * 證書信任管理器(用于https請求) * * @author xinz * @date 2015-10-14 */ public class MyX509TrustManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }
微信返回參數的一個POJO類:
Java代碼
private String openid; //用戶的唯一標識 private String nickname;//用戶昵稱 private Integer sex;// 用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知 private String province;//用戶個人資料填寫的省份 private String city;//普通用戶個人資料填寫的城市 private String country;// 國家,如中國為CN private String headimgurl; // 用戶頭像,最后一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空。若用戶更換頭像,原有頭像URL將失效。 private String privilege;// 用戶特權信息,json 數組,如微信沃卡用戶為(chinaunicom) private String unionid;// 只有在用戶將公眾號綁定到微信開放平臺帳號后,才會出現該字段。詳見:獲取用戶個人信息(UnionID機制) private String access_token;
授權憑證驗證的類:
Java代碼
private String errcode; private String errmsg;
通過code換取網頁授權access_token
Java代碼
private String access_token; private String expires_in; private String refresh_token; private String openid; private String scope; private String unionid;
關于微信頭像的,獲取的是一個http的url,則需要將圖片下載到服務器存儲,然后獲得相對路徑:
Java代碼
/** * 使用url或者http存入文件 * @Title: fileUpload * @param @param fileUrl 文件url,可以是http * @param @param path 文件存儲路徑 * @return void * @throws xinz */ public static void fileUpload (String fileUrl,String path){ //讀取文件 String s1 = fileUrl; java.io.InputStream is = null; //定義一個輸入流。 BufferedInputStream bis = null;//定義一個帶緩沖的輸入流 。 //寫到本地 BufferedOutputStream bos = null; //定義一個帶緩沖的輸出流。 try{ java.net.URL url = new java.net.URL(s1);//創建一個URL對象。 is = url.openStream();//打開到此 URL 的連接并返回一個用于從該連接讀入的 InputStream。 bis = new java.io.BufferedInputStream(is); File file = new File(path); if(!file.exists()){ //測試此抽象路徑名表示的文件或目錄是否存在。 file.createNewFile(); //創建此抽象路徑名表示的文件或目錄。 } bos = new BufferedOutputStream(new FileOutputStream(file));; byte[] b = new byte[1024]; //創建字節數組。 while(bis.read(b)!=-1){//輸入流中的數據如果還有下一行(!=-1)將繼續循環 bos.write(b);//將字節數組寫入輸出流。 } }catch(Exception e){ System.out.println(e.toString()); }finally{ try{ bos.flush();//刷新此緩沖的輸出流。 bis.close(); //關閉此輸入流 。 }catch(Exception e){ System.out.println(e.toString()); } } }
現在是基礎工作都做完了,現在開發代碼的開發,在微信開發文檔中 http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html 有提到每一個步驟,然后我們按照這個步驟開發:
1第一步:用戶同意授權,獲取code
2第二步:通過code換取網頁授權access_token
3第三步:刷新access_token(如果需要)
4第四步:拉取用戶信息(需scope為 snsapi_userinfo)
5附:檢驗授權憑證(access_token)是否有效
第一步:用戶同意授權,獲取code
這里的url就是前面所準備在properties中的url了。
Java代碼
/** * 微信用戶授權 * @Title: wechatOauth * @param @param request * @param @param response * @param @param model * @param @return * @return String * @throws xinz */ @RequestMapping("wechatOauth") public String wechatOauth(HttpServletRequest request,HttpServletResponse response,Model model) { /** * 1 第一步:用戶同意授權,獲取code */ //首先拿到微信公眾號的AppID、AppSecret等參數 String AppID = ZhtxHelper.getApplicationResourcesProp("sendSms","AppID"); String urlOpen = ZhtxHelper.getApplicationResourcesProp("sendSms","url"); //如果用戶授權成功則跳轉到此url String loginUrl = ""+urlOpen+"/zhtx-wap/weixin/getAccessToken"; //用戶授權,獲取code String url = "https://open.weixin.qq.com/connect/oauth3/authorize?" + "appid="+AppID+"" + "&redirect_uri="+loginUrl+"" + "&response_type=code" + "&scope=snsapi_userinfo" + "&state=123#wechat_redirect"; //forward redirect return "redirect:"+url+""; }
Java代碼
/** * 通過code換取網頁授權access_token * @Title: getAccessToken * @param @param request * @param @param response * @param @param model * @param @return * @return String * @throws xinz */ @RequestMapping("getAccessToken") public String getAccessToken(HttpServletRequest request,HttpServletResponse response,Model model) { //獲取到返回的參數 try { //首先拿到微信公眾號的AppID、AppSecret等參數 String AppID = ZhtxHelper.getApplicationResourcesProp("sendSms","AppID"); String AppSecret = ZhtxHelper.getApplicationResourcesProp("sendSms","AppSecret"); String code = request.getParameter("code"); String url = null; if(code!=null){ /** * 2 第二步:通過code換取網頁授權access_token */ //用戶授權,獲取code url = "https://api.weixin.qq.com/sns/oauth3/access_token?" + "appid="+AppID+"" + "&secret="+AppSecret+"" + "&code="+code+"" + "&grant_type=authorization_code"; String requestMethod = "GET"; String outputStr = ""; String httpRequest = WeixinUtil.httpRequest(url, requestMethod, outputStr); System.out.println("通過code換取網頁授權access_token="+httpRequest); AccessTokenModel accTok = JSON.parseObject(httpRequest, AccessTokenModel.class); /** * 4 第四步:拉取用戶信息(需scope為 snsapi_userinfo) */ //用戶授權,獲取code String urlUser = "https://api.weixin.qq.com/sns/userinfo?" + "access_token="+accTok.getAccess_token()+"" + "&openid="+accTok.getOpenid()+"" + "&lang=zh_CN"; String httpUser = WeixinUtil.httpRequest(urlUser, requestMethod, outputStr); System.out.println("拉取用戶信息=="+httpUser); WechatUser wechatUser = JSON.parseObject(httpUser, WechatUser.class); wechatUser.setAccess_token(accTok.getAccess_token()); /** * 5 附:檢驗授權憑證(access_token)是否有效 */ WechatMsg checkAccessToken = checkAccessToken(wechatUser.getAccess_token(), wechatUser.getOpenid()); if(checkAccessToken.getErrcode().equals("0")){ CurrentSession.setAttribute("wechatUser", wechatUser); WechatUser wechatU = new WechatUser(); wechatU.setOpenid(wechatUser.getOpenid()); List<WechatUser> findWechatUser = wechatUserService.findWechatUser(wechatU); if(findWechatUser.size()>0){ UserRegister userRegister = userService.findUserByOpenid(wechatUser.getOpenid()); CurrentSession.setAttribute("user", userRegister); return "redirect:/user/userCenter"; }else{ return "/jsp/wechat/wechatregister"; } }else{ //如果access_token失效,則再次進行調用,并存儲access_token值,access_token有效期為2個小時 this.wechatOauth(request, response, model); } } } catch (Exception e) { System.out.println("===拉取用戶出錯==="); e.printStackTrace(); } //forward redirect return "/jsp/wechat/wechatregister"; }
Java代碼
/** * 微信關聯用戶 * @Title: saveWechatUser * @param @param mobilePhone * @param @param password * @param @param validataCode * @param @return * @return String * @throws xinz */ @RequestMapping("saveWechatUser") public String saveWechatUser(HttpServletResponse response,String mobilePhone,String password,String validataCode){ //使用手機號來判斷該手機是否在注冊 UserRegister userRegister = userService.findUserByPhone(mobilePhone); WechatUser wechatUser = (WechatUser)CurrentSession.getAttribute("wechatUser"); WechatUser wechatU = new WechatUser(); wechatU.setOpenid(wechatUser.getOpenid()); List<WechatUser> findWechatUser = wechatUserService.findWechatUser(wechatU); if(findWechatUser.size()>0 && userRegister.getOpenid()!=null){ CurrentSession.setAttribute("user", userRegister); return "redirect:/user/userCenter"; }else{ //如果沒有注冊,開始注冊 if(userRegister==null){ Result<UserRegister> saveUserInfoApp = userRegisterService.saveUserInfoApp(mobilePhone, password, validataCode,wechatUser); if(saveUserInfoApp.getState()==1){ //進行微信和用戶的關聯 wechatUserService.saveWechatUser(wechatUser); CurrentSession.setAttribute("user", userRegister); return "redirect:/user/userCenter"; } }else if(userRegister.getOpenid()==null || userRegister.getOpenid().equals("")){ //否則,查詢出用戶信息,放入session中,關聯微信,跳轉到用戶中心 UserRegister userReg = new UserRegister(); userReg.setId(userRegister.getId()); //存入微信openid userReg.setOpenid(wechatUser.getOpenid()); userService.upUser(userReg); UserInfo user = new UserInfo(); //存入微信頭像 //圖片類型 String dateStr =DateUtil.format(DateUtil.getCurrentDate(), "yyyyMMdd") + "/"; //圖片類型 String imgType = "JPG"; //微信頭像名稱 String app2DBarNameAndType = UuidUtil.getUUID()+"."+imgType; //微信頭像路徑 String path = ZhtxHelper.getApplicationResourcesProp("application","app.img.projectpath")+ SysConstant.GOODS2DBARPATH + dateStr; File file1 = new File(path); file1.mkdirs(); //圖片全路徑 String imgUrl = SysConstant.GOODS2DBARPATH + dateStr+app2DBarNameAndType; FileUtil.fileUpload(wechatUser.getHeadimgurl(), path); user.setRegisterId(userRegister.getId()); user.setImageUrl(imgUrl); userInfoService.updateUserInfo(user); //存入微信用戶 wechatUserService.saveWechatUser(wechatUser); UserRegister userW = userService.findUserByPhone(mobilePhone); CurrentSession.setAttribute("user", userW); return "redirect:/user/userCenter"; }else{ CurrentSession.setAttribute("user", userRegister); return "redirect:/user/userCenter"; } } return "redirect:/user/userCenter"; }
Java代碼
/** * 檢驗授權憑證(access_token)是否有效 * @Title: checkAccessToken * @param @param access_token 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同 * @param @param openid 用戶的唯一標識 * @return WechatMsg 返回消息實體 * @throws xinz */ public static WechatMsg checkAccessToken(String access_token,String openid){ String requestMethod = "GET"; String outputStr = ""; String url = "https://api.weixin.qq.com/sns/auth?" + "access_token="+access_token+"" + "&openid="+openid+""; String httpmsg = WeixinUtil.httpRequest(url, requestMethod, outputStr); System.out.println("拉取用戶信息返回消息=="+httpmsg); WechatMsg msg = JSON.parseObject(httpmsg, WechatMsg.class); return msg; }
然后在網頁端,則是需要編寫H5頁面,進行自己網站和微信用戶的關聯,我這里是使用手機號,用戶輸入手機號,進行判斷,如果注冊過就直接關聯,如果用戶沒有注冊則進行注冊后關聯,完成后跳轉到會員中心。
以上是“微信開發之如何獲取OAuth2.0網頁授權認證和獲取用戶信息進行關聯”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。