溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

微信開發(fā)之Author網(wǎng)頁授權(quán)的示例分析

發(fā)布時(shí)間:2021-09-06 15:46:32 來源:億速云 閱讀:138 作者:小新 欄目:移動(dòng)開發(fā)

這篇文章主要介紹微信開發(fā)之Author網(wǎng)頁授權(quán)的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

微信開發(fā)中,經(jīng)常有這樣的需求:獲得用戶頭像、綁定微信號給用戶發(fā)信息.. 那么實(shí)現(xiàn)這些的前提就是授權(quán)!

1.配置安全回調(diào)域名:

微信開發(fā)之Author網(wǎng)頁授權(quán)的示例分析

在微信公眾號請求用戶網(wǎng)頁授權(quán)之前,開發(fā)者需要先到公眾平臺(tái)官網(wǎng)中的“開發(fā) - 接口權(quán)限 - 網(wǎng)頁服務(wù) - 網(wǎng)頁帳號 - 網(wǎng)頁授權(quán)獲取用戶基本信息”的配置選項(xiàng)中,修改授權(quán)回調(diào)域名,值得注意的是這里就是直接寫全域名,如: www.liliangel.cn。然而我們開發(fā)h6中一般用的是二級域名,如:h6.liliangel.cn 也同樣在安全回調(diào)域名中。

微信開發(fā)之Author網(wǎng)頁授權(quán)的示例分析

微信更新后,授權(quán)頁也變化了。其實(shí)習(xí)慣了綠色的那個(gè)經(jīng)典頁面..

js:
var center = {
        init: function(){
            .....
        },
        enterWxAuthor: function(){
            var wxUserInfo = localStorage.getItem("wxUserInfo");
            if (!wxUserInfo) {
                var code = common.getUrlParameter('code');
                if (code) {
                    common.getWxUserInfo();
                    center.init();
                }else{
                    //沒有微信用戶信息,沒有授權(quán)-->> 需要授權(quán),跳轉(zhuǎn)授權(quán)頁面
                    window.location.href = 'https://open.weixin.qq.com/connect/oauth3/authorize?appid='+ WX_APPID +'&redirect_uri='+ window.location.href +'&response_type=code&scope=snsapi_userinfo#wechat_redirect';
                }
            }else{
                center.init();
            }
        }
}
$(document).ready(function() { 
    center.enterWxAuthor();
}

以scope=snsapi_userinfo為例,頁面加載的時(shí)候進(jìn)入授權(quán)方法,首先從緩存獲取wxUserInfo對象,如果有說明之前已經(jīng)授權(quán)過,直接進(jìn)入初始化方法。如果沒有,判斷url是否包含code,有code說明是進(jìn)入授權(quán)頁回調(diào)后的頁面,那么通過code換取用戶信息即可。沒有code,即用戶第一次進(jìn)入該頁面,引導(dǎo)去授權(quán)頁,redirect_uri為當(dāng)前頁面地址。

getWxUserInfo方法:
/**
     * 授權(quán)后獲取用戶的基本信息
     */
    getWxUserInfo:function(par){
        var code = common.getUrlParameter("code");
        
        if (par) code = par;
        
        $.ajax({
            async: false,
            data: {code:code},
            type : "GET",
            url : WX_ROOT + "wechat/authorization",
            success : function(json) {
                if (json){
                    try {
                        //保證寫入的wxUserInfo是正確的
                        var data = JSON.parse(json);
                        if (data.openid) {
                            localStorage.setItem('wxUserInfo',json);//寫緩存--微信用戶信息
                        }
                    } catch (e) {
                        // TODO: handle exception
                    }
                }
            }
        });
    },

5.后臺(tái)restful-- /wechat/authorization,根據(jù)code換取用戶信息

  /**
     * 微信授權(quán)
     * @param code 使用一次后失效
     * 
     * @return 用戶基本信息
     * @throws IOException 
     */
    @RequestMapping(value = "/authorization", method = RequestMethod.GET)    public void authorizationWeixin(
            @RequestParam String code,
            HttpServletRequest request, 
            HttpServletResponse response) throws IOException{
        request.setCharacterEncoding("UTF-8");  
        response.setCharacterEncoding("UTF-8"); 

        PrintWriter out = response.getWriter();
        LOGGER.info("RestFul of authorization parameters code:{}",code);        
        try {
            String rs = wechatService.getOauthAccessToken(code);
            out.write(rs);
            LOGGER.info("RestFul of authorization is successful.",rs);
        } catch (Exception e) {
            LOGGER.error("RestFul of authorization is error.",e);
        }finally{
            out.close();
        }
    }

這里有一個(gè)授權(quán)access_token,切記:授權(quán)access_token非全局access_token ,需要使用緩存,這里我使用的redis,具體配置不多說后面寫相關(guān)配置博文,當(dāng)然也可以使用ehcache,關(guān)于ehcahe配置在我的第一篇博客中有詳細(xì)介紹。

  /**
     * 根據(jù)code 獲取授權(quán)的token 僅限授權(quán)時(shí)使用,與全局的access_token不同
     * @param code
     * @return
     * @throws IOException 
     * @throws ClientProtocolException 
     */
    public String getOauthAccessToken(String code) throws ClientProtocolException, IOException{
        String data = redisService.get("WEIXIN_SQ_ACCESS_TOKEN");
        String rs_access_token = null;
        String rs_openid = null;
        String url = WX_OAUTH_ACCESS_TOKEN_URL + "?appid="+WX_APPID+"&secret="+WX_APPSECRET+"&code="+code+"&grant_type=authorization_code";        if (StringUtils.isEmpty(data)) {            synchronized (this) {                //已過期,需要刷新
                String hs = apiService.doGet(url);
                JSONObject json = JSONObject.parseObject(hs);
                String refresh_token = json.getString("refresh_token");
    
                String refresh_url = "https://api.weixin.qq.com/sns/oauth3/refresh_token?appid="+WX_APPID+"&grant_type=refresh_token&refresh_token="+refresh_token;
                String r_hs = apiService.doGet(refresh_url);
                JSONObject r_json = JSONObject.parseObject(r_hs);
                String r_access_token = r_json.getString("access_token");
                String r_expires_in = r_json.getString("expires_in");
                rs_openid = r_json.getString("openid");
                
                rs_access_token = r_access_token;
                redisService.set("WEIXIN_SQ_ACCESS_TOKEN", r_access_token, Integer.parseInt(r_expires_in) - 3600);
                LOGGER.info("Set sq access_token to redis is successful.parameters time:{},realtime",Integer.parseInt(r_expires_in), Integer.parseInt(r_expires_in) - 3600);
            }
        }else{            //還沒有過期
            String hs = apiService.doGet(url);
            JSONObject json = JSONObject.parseObject(hs);
            rs_access_token = json.getString("access_token");
            rs_openid = json.getString("openid");
            LOGGER.info("Get sq access_token from redis is successful.rs_access_token:{},rs_openid:{}",rs_access_token,rs_openid);
        }        
        return getOauthUserInfo(rs_access_token,rs_openid);
    }
  /**
     * 根據(jù)授權(quán)token獲取用戶信息
     * @param access_token
     * @param openid
     * @return
     */
    public String getOauthUserInfo(String access_token,String openid){
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+ access_token +"&openid="+ openid +"&lang=zh_CN";        
        try {
            String hs = apiService.doGet(url);            
            //保存用戶信息            
            saveWeixinUser(hs);            
            return hs;
        } catch (IOException e) {
            LOGGER.error("RestFul of authorization is error.",e);
        }        
        return null;
    }

當(dāng)時(shí)趕時(shí)間,代碼命名較亂??梢钥吹?,我用了一個(gè)同步的方法,先從緩存中獲取key為WEIXIN_SQ_ACCESS_TOKEN,如果取到了說明沒有過期,直接通過httpclient調(diào)用微信提供的接口,返回用戶信息的字符串給前端。如果沒有取到,說明沒有或者已經(jīng)過期,則根據(jù)refresh_token刷新access_token,再寫緩存,由于access_token擁有較短的有效期,為了保險(xiǎn)我這里設(shè)置了緩存的失效時(shí)間微信給的時(shí)間再減一個(gè)小時(shí)。回過頭來看代碼發(fā)現(xiàn),上面的邏輯有點(diǎn)點(diǎn)小問題,這樣寫會(huì)導(dǎo)致第一次獲取或者緩存失效后第一次獲取access_token都會(huì)去刷新一次,暫時(shí)不影響使用,后面做優(yōu)化修改 TODO。

6:保存用戶信息

通常情況下,授權(quán)后我們會(huì)將用戶信息保存數(shù)據(jù)庫表,openid為唯一主鍵,外鍵關(guān)聯(lián)起我們自己的用戶表,這樣一來,無論是后續(xù)要開展什么業(yè)務(wù),還是做運(yùn)營數(shù)據(jù)統(tǒng)計(jì),都有了一個(gè)跟微信公眾號的關(guān)聯(lián)關(guān)系。值得注意的是:我們獲取到的headimgurl是微信提供的一個(gè)url地址,當(dāng)用戶修改頭像后可能導(dǎo)致原來的地址失效,所以最好是通過將圖片保存到本地服務(wù)器然后保存本地的地址url!

微信返回的值:

微信開發(fā)之Author網(wǎng)頁授權(quán)的示例分析

以上是“微信開發(fā)之Author網(wǎng)頁授權(quán)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI