網(wǎng)頁授權(quán)-前后端分離(springboot+vue)

0.官方文檔

微信網(wǎng)頁授權(quán)步驟 --> 傳送門

1 第一步:用戶同意授權(quán)十艾,獲取code
2 第二步:通過code換取網(wǎng)頁授權(quán)access_token
3 第三步:刷新access_token(如果需要)
4 第四步:拉取用戶信息(需scope為 snsapi_userinfo)
5 附:檢驗授權(quán)憑證(access_token)是否有效

1.第一步:用戶同意授權(quán),獲取code

組裝鑒權(quán)鏈接--->
在確保微信公眾賬號擁有授權(quán)作用域(scope參數(shù))的權(quán)限的前提下(服務(wù)號獲得高級接口后查剖,默認(rèn)擁有scope參數(shù)中的snsapi_base和snsapi_userinfo)飒泻,引導(dǎo)關(guān)注者打開如下頁面(直接把url貼到微信鞭光,打開鏈接即可):

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

若提示“該鏈接無法訪問”啊掏,請檢查參數(shù)是否填寫錯誤,是否擁有scope參數(shù)對應(yīng)的授權(quán)作用域權(quán)限衰猛。
首先做一個你內(nèi)網(wǎng)穿透:
https://ray.ngrok.xiaomiqiu.cn 是我本地做的一個內(nèi)網(wǎng)穿透(小米球)迟蜜,映射到本地6001服務(wù)。

image.png

我的:

https://open.weixin.qq.com/connect/oauth2/authorize?appid="+ appid + "&redirect_uri=https%3a%2f%2fray.ngrok.xiaomiqiu.cn%2fwechat%2fgetCode&response_type=code&scope=snsapi_userinfo&state=xxx#wechat_redirect
注意:回調(diào)redirect_uri的值需要encode-->
https://ray.ngrok.xiaomiqiu.cn/wechat/getCode  -->utf8-encode--> https%3a%2f%2fray.ngrok.xiaomiqiu.cn%2fwechat%2fgetCode

用戶點擊該url--->微信跳轉(zhuǎn)回調(diào)我們設(shè)置的redirect_uri(https://ray.ngrok.xiaomiqiu.cn/wechat/getCode).
那么我們在

image.png

在里面我們可以獲取微信傳遞給我們的code啡省。

2.通過code換取網(wǎng)頁授權(quán)access_token

    -->>>>>>>>>>獲取code后娜睛,請求以下鏈接請求獲取access_token
    public static final String WEB_GET_ACCESS_REQ_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

    public static WxOauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {
        WxOauth2Token wat = null;
        // 拼接請求地址
        String requestUrl = WEB_GET_ACCESS_REQ_URL;
        requestUrl = requestUrl.replace("APPID", appId);
        requestUrl = requestUrl.replace("SECRET", appSecret);
        requestUrl = requestUrl.replace("CODE", code);
        // 獲取網(wǎng)頁授權(quán)憑證
//        JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
        JSONObject jsonObject = WxUtil.doGetStr(requestUrl);
        if (null != jsonObject) {
            try {
                wat = new WxOauth2Token();
                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");
                logger.error("獲取網(wǎng)頁授權(quán)憑證失敗 errcode:{} errmsg:{}" + errorCode + errorMsg);
            }
        }
        return wat;
    }

    WxOauth2Token weixinOauth2Token = WxWebUtil.getOauth2AccessToken(WxAuth.instance().getAppid(), WxAuth.instance().getAppsec(), code);

現(xiàn)在得到了access_token,可以取到用戶信息了X远谩F杞洹!=嵝颉障斋!

3.第三步:刷新access_token(如果需要)

由于access_token擁有較短的有效期,當(dāng)access_token超時后徐鹤,可以使用refresh_token進(jìn)行刷新垃环,refresh_token有效期為30天,當(dāng)refresh_token失效之后返敬,需要用戶重新授權(quán)遂庄。

獲取第二步的refresh_token后,請求以下鏈接獲取access_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
具體參考官方文檔劲赠。

4.拉取用戶信息(需scope為 snsapi_userinfo)

    /**
     * 通過網(wǎng)頁授權(quán)獲取用戶信息
     * 
     * @param accessToken 網(wǎng)頁授權(quán)接口調(diào)用憑證
     * @param openId 用戶標(biāo)識
     * @return WxWebUserInfo
     */
    @SuppressWarnings({ "deprecation", "unchecked" })
    public static WxWebUserInfo getSNSUserInfo(String accessToken, String openId) {
        WxWebUserInfo 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);
        // 通過網(wǎng)頁授權(quán)獲取用戶信息
        JSONObject jsonObject = WxUtil.doGetStr(requestUrl);
        if (null != jsonObject) {
            try {
                snsUserInfo = new WxWebUserInfo();
                // 用戶的標(biāo)識
                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"));
                // 用戶特權(quán)信息
//              JSONArray.parseArray()
//              snsUserInfo.setPrivilegeList(JSONArray.toList(jsonObject.getJSONArray("privilege"), List.class));
            } catch (Exception e) {
                snsUserInfo = null;
                int errorCode = jsonObject.getInteger("errcode");
                String errorMsg = jsonObject.getString("errmsg");
                logger.error("獲取用戶信息失敗 errcode:{} errmsg:{}" +  errorCode + errorMsg);
            }
        }
        return snsUserInfo;
    }

    //通過第二步凛澎,獲取accesstoken和openid
    WxOauth2Token weixinOauth2Token = WxWebUtil.getOauth2AccessToken(WxAuth.instance().getAppid(), WxAuth.instance().getAppsec(), code);
    // 網(wǎng)頁授權(quán)接口訪問憑證
    String accessToken = weixinOauth2Token.getAccessToken();
    // 用戶標(biāo)識
    openId = weixinOauth2Token.getOpenId();
    // 獲取用戶信息
    WxWebUserInfo snsUserInfo = WxWebUtil.getSNSUserInfo(accessToken, openId);

結(jié)尾處霹肝,重定向到vue前端首頁并帶上唯一標(biāo)志:

    /**
     * 鑒權(quán)回調(diào)
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/getCode")
    public ModelAndView getCode(HttpServletRequest request) {
        String code = request.getParameter("code");
        String state = request.getParameter("state");
        String openId = GlobalConstant.Symbol.EMPTY;
        // 用戶同意授權(quán)
        if (!"authdeny".equals(code)) {
            // 獲取網(wǎng)頁授權(quán)access_token
            WxOauth2Token weixinOauth2Token = WxWebUtil.getOauth2AccessToken(WxAuth.instance().getAppid(), WxAuth.instance().getAppsec(), code);
            // 網(wǎng)頁授權(quán)接口訪問憑證
            String accessToken = weixinOauth2Token.getAccessToken();
            // 用戶標(biāo)識
            openId = weixinOauth2Token.getOpenId();
            // 獲取用戶信息
            WxWebUserInfo snsUserInfo = WxWebUtil.getSNSUserInfo(accessToken, openId);

            if (ObjUtils.isNotEmpty(redisDAO)) {
                redisDAO.set(RedisKeyUtil.getPartnerUserAuthInfoKey(openId), weixinOauth2Token, RedisKeyUtil.EXPIRE_TIME_SEC_MAX);
            }

            log.info("獲取用戶信息: " + snsUserInfo.toString());

            return null;
        }

        // 重定向到vue前端首頁并帶上唯一標(biāo)志, 這里你可以帶上加密后的token,然后前后端識別就使用該token進(jìn)行用戶身份驗證識別塑煎,
        //我在此處簡單處理沫换,就直接用openid,然后前端展示首頁的時候轧叽,截取url里面的內(nèi)容:openid苗沧,然后前端vue就獲取到了openid了。
        //shaw.ngrok.xiaomiqiu.cn是我做的一個內(nèi)網(wǎng)穿透炭晒,指向前端vue頁面待逞。
        String url_to = "http://shaw.ngrok.xiaomiqiu.cn/vue-project?openid=" + openId;


        return new ModelAndView(new RedirectView(url_to));
    }

該鏈接一般設(shè)置到服務(wù)號的菜單欄里面,設(shè)置微信菜單欄网严,后期發(fā)布文章识樱。
我們在手機端點擊開那個鑒權(quán)鏈接,經(jīng)過上面的操作之后,就會重定向到后臺設(shè)置的跳轉(zhuǎn)到vue項目首頁怜庸。首頁通過openid獲取服務(wù)器數(shù)據(jù)当犯。

5.前端部分:

我做的是將前端打包放到tomcat下

image.png

webapps\vue-project
--static
--index.html
然后tomcat(端口8080)跑起來,做一個內(nèi)網(wǎng)穿透
image.png

http://shaw.ngrok.xiaomiqiu.cn --> 127.0.0.1:8080
服務(wù)端重定向到這個地址割疾,那么前端vue的頁面就展示到微信里面了嚎卫。
OK!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宏榕,一起剝皮案震驚了整個濱河市拓诸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌麻昼,老刑警劉巖奠支,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異抚芦,居然都是意外死亡倍谜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門叉抡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尔崔,“玉大人,你說我怎么就攤上這事卜壕∧裕” “怎么了烙常?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵轴捎,是天一觀的道長。 經(jīng)常有香客問我蚕脏,道長侦副,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任驼鞭,我火速辦了婚禮秦驯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挣棕。我一直安慰自己译隘,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布洛心。 她就那樣靜靜地躺著固耘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪词身。 梳的紋絲不亂的頭發(fā)上厅目,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音,去河邊找鬼损敷。 笑死葫笼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拗馒。 我是一名探鬼主播路星,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼诱桂!你這毒婦竟也來了奥额?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤访诱,失蹤者是張志新(化名)和其女友劉穎垫挨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體触菜,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡九榔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了涡相。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哲泊。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖催蝗,靈堂內(nèi)的尸體忽然破棺而出切威,到底是詐尸還是另有隱情,我是刑警寧澤丙号,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布先朦,位于F島的核電站,受9級特大地震影響犬缨,放射性物質(zhì)發(fā)生泄漏喳魏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一怀薛、第九天 我趴在偏房一處隱蔽的房頂上張望刺彩。 院中可真熱鬧,春花似錦枝恋、人聲如沸创倔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽畦攘。三九已至,卻和暖如春呐能,著一層夾襖步出監(jiān)牢的瞬間念搬,已是汗流浹背抑堡。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留朗徊,地道東北人首妖。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像爷恳,于是被迫代替她去往敵國和親有缆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容