如何獲取微信openId

獲取微信openid

openid定義

為了識別用戶,每個用戶針對每個公眾號會產(chǎn)生一個安全的OpenID,如果需要在多公眾號、移動應(yīng)用之間做用戶共通,則需前往微信開放平臺,將這些公眾號和應(yīng)用綁定到一個開放平臺賬號下,綁定后,一個用戶雖然對多個公眾號和應(yīng)用有多個不同的OpenID。所以一個微信號在一個公眾號下的openid是不變的,如果換了一個對應(yīng)的公眾號,那就是另一個openid了。且只有在微信自帶瀏覽器中打開的項目才可獲取到。

準(zhǔn)備條件

因為一個openid對應(yīng)一個微信用戶一個公眾號,所以首先你要有一個公眾號,還有一個外網(wǎng)可訪問的域名,我的公眾號類型是企業(yè)號,這里就以企業(yè)號為例。

獲取openid需要的公眾號的 appid 和 secret(登陸公眾平臺 開發(fā)----->基本配置中的開發(fā)者ID(AppID)和 開發(fā)者密碼(AppSecret)就是)。

5b2ca57c0c12b
5b2ca57c0c12b

其次是設(shè)置網(wǎng)頁授權(quán)域名(登陸公眾平臺 設(shè)置----->公眾號設(shè)置------>功能設(shè)置----->網(wǎng)頁授權(quán)域名 按步驟操作并設(shè)置就好),這個域名就是你獲取openid的web項目發(fā)布的域名,這里注意服務(wù)器請一定跑在80端口

基本流程:

openid作為用戶信息的一部分,要獲取到需要調(diào)用微信兩個開放授權(quán)接口,接口遵循OAuth 2.0協(xié)議。開放授權(quán)標(biāo)準(zhǔn)允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲的私密的資源(如照片,視頻,聯(lián)系人列表),而無需將用戶名和密碼提供給第三方應(yīng)用,也就是我們常用的微信登錄、微博登錄等等,英文好的同學(xué)可以看看OAuth 2.0 Authorization Framework。

我整理了一下整體的流程,畫了一個時序圖。

image.png

其中兩次調(diào)用了微信嗯驗證服務(wù)器。

  1. 調(diào)用https://open.weixin.qq.com/connect/oauth2/authorize 接口獲取到code,注意這個接口只獲取openid,scope參數(shù)設(shè)置為snsapi_base,這樣不需要用戶確認(rèn)和關(guān)注公眾號。

不知道你有沒有疑問,為什么不直接獲取openId,還需要獲取一個code呢?

是因為code相當(dāng)于一個臨時票據(jù),能夠驗證失效時間、可獲取信息的內(nèi)容、微信用戶、appid等等。

  1. 得到code作為一個參數(shù),加上appId和appsecret,調(diào)用https://api.weixin.qq.com/sns/oauth2/access_token 接口獲取到openid。

注意,appsecret是比較重要的參數(shù)要放到后臺進(jìn)行請求。返回的重要參數(shù)又openId和access_token,用openId和access_token可以獲取用戶的基本信息,位置性別等等等,我們這里只講獲取openId,原理類似,想看參考微信網(wǎng)頁授權(quán)。

代碼

前端

    function openId(){
        //測試
        var callbackUrl = link.skip + itemId;
        var appid = link.appid;
        var redirect_uri = encodeURI(callbackUrl);
        var code = requestUtil.getParameter('code');
        if (code && localStorage.getItem('code') != code) {
          //微信回調(diào)含code調(diào)用免登陸接口,否則跳轉(zhuǎn)微信驗證
          $.ajax({
            type: 'get',
            url: link.path+"/v1/wechatUser/info?code=" + code,
            async: false,
            success: function (res) {
                if(res.code == 1000) {
                    localStorage.setItem('code', code);
                    var openId = res.data.openId;
                    localStorage.setItem('openId', openId);
                }
            }
          });
        } else {
            window.location. + appid + '&redirect_uri=' + redirect_uri  + '&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect';
        }
    }

后端

    public void getOpenId(HttpServletRequest request, HttpServletResponse response,String code) throws UnsupportedEncodingException {
        response.setContentType("text/html");
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        Map params = new HashMap();
        params.put("secret", "");
        params.put("appid", "");
        params.put("grant_type", "authorization_code");
        params.put("code", code);
        String result = HttpGetUtil.httpRequestToString(
                "https://api.weixin.qq.com/sns/oauth2/access_token", params);
        JSONObject jsonObject = JSONObject.parseObject(result);

        String openid = jsonObject.get("openid").toString();
        System.out.println("得到的openid為:"+openid);
    }
 static class HttpGetUtil {

        public static String httpRequestToString(String url,
                                                 Map params) {
            String result = null;
            try {
                InputStream is = httpRequestToStream(url,  params);
                BufferedReader in = new BufferedReader(new InputStreamReader(is,
                        "UTF-8"));
                StringBuffer buffer = new StringBuffer();
                String line = "";
                while ((line = in.readLine()) != null) {
                    buffer.append(line);
                }
                result = buffer.toString();
            } catch (Exception e) {
                return null;
            }
            return result;
        }

        private static InputStream httpRequestToStream(String url,
                                                       Map params) {
            InputStream is = null;
            try {
                String parameters = "";
                boolean hasParams = false;
                for(String key : params.keySet()){
                    String value = URLEncoder.encode(params.get(key), "UTF-8");
                    parameters += key +"="+ value +"&";
                    hasParams = true;
                }
                if(hasParams){
                    parameters = parameters.substring(0, parameters.length()-1);
                }

                url += "?"+ parameters;

                URL u = new URL(url);
                HttpURLConnection conn = (HttpURLConnection) u.openConnection();
                conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                conn.setRequestProperty("Accept-Charset", "UTF-8");
                conn.setRequestProperty("contentType", "utf-8");
                conn.setConnectTimeout(50000);
                conn.setReadTimeout(50000);
                conn.setDoInput(true);
                //設(shè)置請求方式,默認(rèn)為GET
                conn.setRequestMethod("GET");

                is = conn.getInputStream();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return is;
        }

    }

問題補(bǔ)充

authorize接口:

  1. authorize接口,只能通過微信,或者微信開發(fā)這工具打開(需要加開發(fā)權(quán)限)。

access_token接口:

  1. 如果返回40163錯誤,是因為code已經(jīng)被用過,code只有一次生命,用完作廢。如果出現(xiàn)了code請檢查一下接口1相關(guān)的代碼,是不是對code進(jìn)行了保存等等。

感謝

感謝各位看完這篇文章,如果有問題或不清楚直接留言,或者加vx34108314。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容