最近有做了關于微信公眾號和自己網站用戶進行用戶關聯授權登錄的一個功能,主要是用戶關注該公眾號,點擊會員中心,則會彈出需要關聯授權的網頁授權:OAuth2.0網頁授權,然后用戶同意獲取用戶信息,進行用戶和網站的關聯,然后用戶則可以使用微信進行登錄。
??????? 本次做的是一個在Java的Action層處理各個返回參數獲取數據。
???????一、 使用到的工具:
??????????? 1、ngrok,將你自己的本機映射到公網,這樣保證可以隨時測試開發;
?????????????????? 1、下載ngrok,網址:http://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;?????????????public?class?WeixinUtil?{??????private?static?Logger?log?=?LoggerFactory.getLogger(WeixinUtil.class);?????????????????????public?static?String?httpRequest(String?requestUrl,?String?requestMethod,?String?outputStr)?{??????????StringBuffer?buffer?=?new?StringBuffer();??????????try?{????????????????????????????TrustManager[]?tm?=?{?new?MyX509TrustManager()?};??????????????SSLContext?sslContext?=?SSLContext.getInstance("SSL",?"SunJSSE");??????????????sslContext.init(null,?tm,?new?java.security.SecureRandom());????????????????????????????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);????????????????????????????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;???????????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;??private?String??province;??private?String??city;??private?String??country;??private?String??headimgurl;????private?String??privilege;??private?String??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代碼??
?????????????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);??????????????is?=?url.openStream();??????????????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){????????????????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代碼??
???????????????@RequestMapping("wechatOauth")??????public?String?wechatOauth(HttpServletRequest?request,HttpServletResponse?response,Model?model)??{????????????????????????????????String?AppID?=?ZhtxHelper.getApplicationResourcesProp("sendSms","AppID");??????????String?urlOpen?=?ZhtxHelper.getApplicationResourcesProp("sendSms","url");????????????????????String?loginUrl?=?""+urlOpen+"/zhtx-wap/weixin/getAccessToken";????????????????????String?url?=?"https://open.weixin.qq.com/connect/oauth2/authorize?"??????????????????????+?"appid="+AppID+""??????????????????????+?"&redirect_uri="+loginUrl+""??????????????????????+?"&response_type=code"??????????????????????+?"&scope=snsapi_userinfo"??????????????????????+?"&state=123#wechat_redirect";????????????????????return?"redirect:"+url+"";???????}??
?
第二步:通過code換取網頁授權access_token
?
Java代碼??
???????????????@RequestMapping("getAccessToken")??????public?String?getAccessToken(HttpServletRequest?request,HttpServletResponse?response,Model?model)?{????????????????????try?{????????????????????????????String?AppID?=?ZhtxHelper.getApplicationResourcesProp("sendSms","AppID");??????????????String?AppSecret?=?ZhtxHelper.getApplicationResourcesProp("sendSms","AppSecret");??????????????String?code?=?request.getParameter("code");??????????????String?url?=?null;??????????????if(code!=null){????????????????????????????????????????????????????????url?=?"https://api.weixin.qq.com/sns/oauth2/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);???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????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());??????????????????????????????????????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{????????????????????????????????????????????this.wechatOauth(request,?response,?model);???????????????????}??????????????}??????????}?catch?(Exception?e)?{??????????????System.out.println("===拉取用戶出錯===");??????????????e.printStackTrace();??????????}????????????????????return?"/jsp/wechat/wechatregister";???????}??
?
第四步:拉取用戶,和自己網站用戶綁定
Java代碼??
???????????????@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("")){????????????????????????????????UserRegister?userReg?=?new?UserRegister();??????????????????userReg.setId(userRegister.getId());????????????????????????????????????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";??????}??
?
附:檢驗授權憑證(access_token)是否有效
?
Java代碼??
?????????????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网页授权认证和获取用户信息进行关联(转:http://playxinz.iteye.com/blog/2249634)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。