https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=aa96840e02282c418d755b333218e800ed53f04e&lang=zh_CNjava
這個是微信開發官網上的,絕對正確.web
好,如今開始微信登陸流程.json
1:引導用戶打開受權頁面api
能夠作一個 a 標籤,href="數組
https://open.weixin.qq.com/connect/qrconnect?瀏覽器
appid=APPID服務器
&redirect_uri=REDIRECT_URI微信
&response_type=code微信開發
&scope=SCOPEapp
&state=STATE#wechat_redirect"
其中APPID爲你申請以後微信官網給你的,
redirect_uri爲用戶點擊手機上的贊成以後的回調地址,即用戶贊成以後,網頁就會跳到你寫的地址上,而且這個url須要 UrlEncode編碼 才能夠.(這個url必須和你申請的時候寫的同樣.好比,你申請的時候,填寫的是 www.wowowo.com 如今寫的時候,必須是 http://www.wowowo.com/weixin 這樣子.並且要通過編碼.後面的weixin是我本身加的,你能夠換成本身的.用戶贊成以後,瀏覽器就會從受權頁面跳到
http:www.wowowo.com/weixin?code=XXXXXX&state=state)
scope直接填 snsapi_login
state 能夠不寫,也能夠寫,建議寫上,由於 用戶贊成以後,會回跳到你本身寫的url上,而且會帶上參數code和state.你給了什麼state,返回來的url上跟着什麼state
一開始的時候,我一直打不開受權頁面,配置也沒錯,也不知道爲何.後來直接用 http:www.wowowo.com,後面不加別的路徑,跳到首頁以後,用java代碼獲取code和state,判斷不爲空而且state.equals(本身給的state),知足條件以後就跳,記得附帶上code參數.
2:經過用戶受權獲得的code,進一步獲得用戶的openID和基礎信息.
下面開始貼個人代碼.
web.xml中的代碼:
<servlet-mapping>
<servlet-name>weixin</servlet-name>
<url-pattern>/weixin</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>weixin</servlet-name>
<servlet-class>com.XXXX.plugin.weixin.WeiXinLoginAfter</servlet-class>
</servlet>
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class WeiXinLoginAfter extends HttpServlet { /** * */ private static final long serialVersionUID = 1992726828107519063L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); // 用戶贊成受權後,能獲取到code String code = request.getParameter("code"); String state = request.getParameter("state"); // 用戶贊成受權 if (!"".equals(code) && "weixin".equals(state)) { //APPSECRET 是申請成功以後給的祕鑰,通常放在資源文件中,須要的時候讀出來. // 獲取網頁受權access_token,下面只獲得了openId,還有 accessToken WeixinOauth2Token weixinOauth2Token = AdvancedUtil.getOauth2AccessToken("wx9a9733ca700029be",PropertiesUtil.getParam("APPSECRET"), code); // 網頁受權接口訪問憑證 String accessToken = weixinOauth2Token.getAccessToken(); // 用戶標識 String openId = weixinOauth2Token.getOpenId(); // 獲取用戶信息(比較具體,有暱稱,頭像url,性別,城市等) SNSUserInfo snsUserInfo = AdvancedUtil.getSNSUserInfo(accessToken, openId); //如今你已經獲得openid和用戶基礎信息,能夠作你想作的了. }else{ } } }
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSONObject; public class AdvancedUtil { private static Logger log = LoggerFactory.getLogger(AdvancedUtil.class); /** * 獲取網頁受權憑證 * * @param appId 公衆帳號的惟一標識 * @param appSecret 公衆帳號的密鑰 * @param code * @return WeixinAouth2Token */ public static WeixinOauth2Token getOauth2AccessToken(String appId, String appSecret, String code) { WeixinOauth2Token wat = null; // 拼接請求地址 String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; requestUrl = requestUrl.replace("APPID", appId); requestUrl = requestUrl.replace("SECRET", appSecret); requestUrl = requestUrl.replace("CODE", code); // 獲取網頁受權憑證 JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null); if (null != jsonObject) { try { wat = new WeixinOauth2Token(); wat.setAccessToken(jsonObject.getString("access_token")); wat.setExpiresIn(jsonObject.getInteger("expires_in")); wat.setRefreshToken(jsonObject.getString("refresh_token")); wat.setOpenId(jsonObject.getString("openid")); wat.setScope(jsonObject.getString("scope")); } catch (Exception e) { wat = null; int errorCode = jsonObject.getInteger("errcode"); String errorMsg = jsonObject.getString("errmsg"); log.error("獲取網頁受權憑證失敗 errcode:{} errmsg:{}", errorCode, errorMsg); } } return wat; } /** * 經過網頁受權獲取用戶信息 * * @param accessToken 網頁受權接口調用憑證 * @param openId 用戶標識 * @return SNSUserInfo */ public static SNSUserInfo getSNSUserInfo(String accessToken, String openId) { SNSUserInfo snsUserInfo = null; // 拼接請求地址 String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID"; requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId); // 經過網頁受權獲取用戶信息 JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null); if (null != jsonObject) { try { snsUserInfo = new SNSUserInfo(); // 用戶的標識 snsUserInfo.setOpenId(jsonObject.getString("openid")); // 暱稱 snsUserInfo.setNickname(jsonObject.getString("nickname")); // 性別(1是男性,2是女性,0是未知) snsUserInfo.setSex(jsonObject.getInteger("sex")); // 用戶所在國家 snsUserInfo.setCountry(jsonObject.getString("country")); // 用戶所在省份 snsUserInfo.setProvince(jsonObject.getString("province")); // 用戶所在城市 snsUserInfo.setCity(jsonObject.getString("city")); // 用戶頭像 snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl")); } catch (Exception e) { snsUserInfo = null; int errorCode = jsonObject.getInteger("errcode"); String errorMsg = jsonObject.getString("errmsg"); log.error("獲取用戶信息失敗 errcode:{} errmsg:{}", errorCode, errorMsg); } } return snsUserInfo; } }
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; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; public class CommonUtil { private static Logger log = LoggerFactory.getLogger(CommonUtil.class); /** * 發送https請求 * * @param requestUrl 請求地址 * @param requestMethod 請求方式(GET、POST) * @param outputStr 提交的數據 * @return JSONObject(經過JSONObject.get(key)的方式獲取json對象的屬性值) */ public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; 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 conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 設置請求方式(GET/POST) conn.setRequestMethod(requestMethod); // 當outputStr不爲null時向輸出流寫數據 if (null != outputStr) { OutputStream outputStream = conn.getOutputStream(); // 注意編碼格式 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 從輸入流讀取返回內容 InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 釋放資源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; conn.disconnect(); jsonObject =JSON.parseObject(buffer.toString()); } catch (ConnectException ce) { log.error("鏈接超時:{}", ce); } catch (Exception e) { log.error("https請求異常:{}", e); } return jsonObject; } }
public class WeixinOauth2Token { // 網頁受權接口調用憑證 private String accessToken; // 憑證有效時長 private int expiresIn; // 用於刷新憑證 private String refreshToken; // 用戶標識 private String openId; // 用戶受權做用域 private String scope; public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public int getExpiresIn() { return expiresIn; } public void setExpiresIn(int expiresIn) { this.expiresIn = expiresIn; } public String getRefreshToken() { return refreshToken; } public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } public String getOpenId() { return openId; } public void setOpenId(String openId) { this.openId = openId; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } }
public class SNSUserInfo { // 用戶標識 private String openId; // 用戶暱稱 private String nickname; // 性別(1是男性,2是女性,0是未知) private int sex; // 國家 private String country; // 省份 private String province; // 城市 private String city; // 用戶頭像連接 private String headImgUrl; public String getOpenId() { return openId; } public void setOpenId(String openId) { this.openId = openId; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getHeadImgUrl() { return headImgUrl; } public void setHeadImgUrl(String headImgUrl) { this.headImgUrl = headImgUrl; } }
import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; /** * 類名: MyX509TrustManager </br> * 描述:信任管理器 </br> * 發佈版本:V1.0 </br> */ public class MyX509TrustManager implements X509TrustManager{ // 檢查客戶端證書 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } // 檢查服務器端證書 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } // 返回受信任的X509證書數組 public X509Certificate[] getAcceptedIssuers() { return null; } }
最後,我用的json是阿里巴巴的fastjson,你使用的時候可能須要轉換.
我也是經過 https://share.weiyun.com/73d6445f788e33fafe603dd1adb8db83
下載別人的代碼,通過修改,作成本身的.但願能夠給你幫助.