微信獲取用戶openid

開發框架:struts2(零配置)html

官方文檔下載地址java

https://mp.weixin.qq.com/paymch/readtemplate?t=mp/business/course3_tmpl&lang=zh_CNweb

PS:下列獲取openid的代碼能夠在柳峯的《微信公衆平臺應用開發方法、技巧與案例》的第六章找到。可是書中關於受權域名以及redirect_uri的關聯寫的不是很詳細,在此主要詳細介紹了出現問題排錯的方向。代碼以爲有疑惑的,能夠看柳大神的書,或者csdn搜索柳峯找相關博客查看。json

首先,咱們須要進入咱們的服務號,點擊左側欄開發者中心--->修改網頁受權獲取用戶基本信息的值,假設咱們對外的ip183.33.212.175tomcat的端口號爲8016,這個修改成183.33.212.175:8016api


建立WeiXinOauth2Token類。改類具備如下屬性:(自行添加getset方法)
tomcat

private String accessToken;
微信

private int expiresIn;
app

private String refeshToken;
微信公衆平臺

private String openId;
框架

private String scope;

調用微信的受權接口

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect


其中要說明的是,redirect_uri必定是在咱們設定網頁受權獲取用戶基本信息的域名下的action,否則微信頁面會提示redirect_uri錯誤(因此,出現該錯誤,各位應該知道如何排錯了)

官方文檔給了下面一段話解釋:

好比須要網頁受權的域名爲:www.qq.com,配置之後此域名下面的頁面http://www.qq.com/music.html、http://www.qq.com/login.html均可以進行 OAuth2.0 鑑權。但http://pay.qq.com、http://music.qq.com、http://qq.com 沒法進行 OAuth2.0 鑑權。

上面一段話是什麼意思呢?

假設個人受權域名爲183.33.212.175:8016,那麼。個人redirect_uri須要爲http://183.33.212.175:8016/wxweb/config/oauth!execute.action特別注意的是前面的http://必需要有,

否則就提示找不到頁面183.33.212.175:8016/wxweb/config /oauth!execute.action?code=XXXXXXXXXX。(這一點被坑了一天)

4 而後將redirect_uri進行encode,具體代碼以下
public static String urlEncodeUTF8(String source){
                String result = source;
                try {
                        result = java.net.URLEncoder.encode(source,"utf-8");
                } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                }
                return result;
}
requestUrl= https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect中的REDIRECT_URI是咱們的redirect_uri 進行encode後的值,APPID爲你服務號的appid.
將上面的requestUrl設置爲圖文連接或者view按鈕連接發送給用戶。

5 獲取用戶openid 

個人redirect_uri對應的action方法爲

public String execute() throws ServletException, IOException{
                // 將請求、響應的編碼均設置爲UTF-8(防止中文亂碼)
                HttpServletRequest request = ServletActionContext.getRequest();
                HttpServletResponse response = ServletActionContext.getResponse();
                request.setCharacterEncoding("UTF-8");
                response.setCharacterEncoding("UTF-8");
                String code = request.getParameter("code");
                String openId ="";
                if (!"authdeny".equals(code)) {
                        WeiXinOauth2Token weiXinOauth2Token = AdvancedUtil
                                        .getOauth2AccessToken("wx0953bae287adfeee",
                                                        "8e81dbc44a84a3c290c0cc3759f85421", code);
                        openId = weiXinOauth2Token.getOpenId();
                }
                request.getSession().setAttribute("openId", openId);
                return "index";
}

AdvancedUtil的方法以下:
public static WeiXinOauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {
                WeiXinOauth2Token wat = new WeiXinOauth2Token();
                String requestUrl = oauth2Url.replace("APPID", appId).replace("SECRET", appSecret).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.getInt("expires_in"));
                                wat.setRefeshToken(jsonObject.getString("refresh_token"));
                                wat.setOpenId(jsonObject.getString("openid"));
                                wat.setScope(jsonObject.getString("scope"));
                        } catch (Exception e) {
                                wat = null;
                                String errorCode = jsonObject.getString("errcode");
                                String errorMsg = jsonObject.getString("errmsg");
                                log.error("獲取網頁受權憑證失敗 errcode{},errMsg", errorCode, errorMsg);
                        }

                }
                return wat;
}
CommmonUtil相關方法以下
/**
         * 發送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);
                        //conn.setRequestProperty("content-type", "application/x-www-form-urlencoded"); 
                        // 當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 = JSONObject.fromObject(buffer.toString());
                } catch (ConnectException ce) {
                        log.error("鏈接超時:{}", ce);
                } catch (Exception e) {
                        log.error("https請求異常:{}", e);
                }
                return jsonObject;
}
測試OK後,會獲得用戶的openid並正確跳轉到oauth_index.jsp頁面。

假設用咱們sae的應用,受權域名寫爲searchinfo.sinaapp.com,其中searchinfo是你的應用名稱。那麼沒有encode前的redirect_uri爲:http://searchinfo.sinaapp.com/config/oauth!execute.action。須要注意的是,你部署的代碼中config/oauth!execute.action方法所在版本必須爲你應用的默認版本。檢測是否可行,直接訪問searchinfo.sinaapp.com/config/oauth!execute.action,若報500空指針,說明填寫正確。找不到方法請自行修改默認版本,找到對應的執行action便可。

相關文章
相關標籤/搜索