微信公眾號03 微信網頁授權


前提准備

域名

開發微信網頁授權時需要一個外網可以訪問的域名,因為用戶確認進行微信網頁授權后微信服務器會通過一個回調URL向開發服務器發送一個回調請求。
開發階段可以使用一些內網穿透工具來實現,例如:natapp、花生殼等等。
福利:natapp和花生殼都會免費贈送一些隧道。
注意:natapp提供的免費隧道每次啟動客戶端時產生的域名時隨機的。
填坑:利用花生殼提供的域名進行內網穿透時可能會被微信攔截,所以推薦使用natapp(PS: 請測有效)。

個人訂閱號

由於是進行微信網頁授權,所以需要一個個人微信訂閱號作為開發基礎。
福利:由於微信個人訂閱號沒有提供微信網頁授權功能,但是可以利用微信提供的測試號進行開發。
測試號在哪里:登錄個人訂閱號 -> 開發 -> 開發者工具 -> 公眾平台測試賬號
注意:整個開發過程中都是使用測試號的appID和appsecret

開發環境

JDK: 1.8
MAVEN: 3.x
SpringBoot: 2.x
IDEA: 2017專業版

微信網頁授權官方文檔

文檔路徑

文檔在哪里:登錄微信訂閱號 -> 開發 -> 開發者工具 -> 開發文檔 -> 微信網頁開發 -> 微信網頁授權

回調域名配置

在哪里配置:登錄個人訂閱號 -> 開發 -> 開發者工具 -> 公眾平台測試賬號 -> 網頁服務 -> 網頁賬號 -> 修改 -> 填入授權回調頁面域名即可(推薦使用natapp)

開發步驟

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

Java代碼實現

進入微信授權頁面

只需要通過微信瀏覽器訪問到微信授權的頁面即可。
思路
01 用戶通過微信瀏覽器進入一個頁面
02 點擊一個按鈕向開發者后台發送一個GET請求
03 開發這個后台封裝一個URL並重定向到這個URL
代碼片段

    /**
     * 微信網頁授權邏輯入口
     * @param map
     */
    @GetMapping(value = "/auth")
    public void toAuth(ModelMap map, HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("進入微信授權邏輯......");
//        微信網頁授權第一步 - 用戶同意授權,獲取code - start
        String getCodeUrl = weixinBaseInfoProperties.getAuth().getGetCodeUrl();
        String appid = weixinBaseInfoProperties.getAppid();
        String appsecret = weixinBaseInfoProperties.getAppsecret();
        String redirectUri = weixinBaseInfoProperties.getAuth().getRedirectUri();
        String scope = weixinBaseInfoProperties.getAuth().getScope();
        getCodeUrl = getCodeUrl.replace("APPID", appid)
                .replace("REDIRECT_URI", redirectUri)
                .replace("SCOPE", scope);
        log.info("封裝好的getCodeUrl為:" + getCodeUrl);
        response.sendRedirect(getCodeUrl);
//        微信網頁授權第一步 - 用戶同意授權,獲取code - end
    }

獲取CODE和AccessToken、用戶openid、用戶信息

微信用戶通過微信瀏覽器確認授權后,微信服務器會通過之前設定的回調URL向開發者后台發送一個GET請求,這個請求中攜帶了CODE信息。
思路
01 用戶確認授權
02 微信服務器發送回調請求
03 開發服務器接收到回調請求
04 獲取CODE
05 通過CODE在拼裝一個url去請求微信服務器來獲取access_token、openid
06 通過access_token、openid封裝一個url去請求微信服務器來獲取用戶信息

微信網頁授權的使用場景

直接利用微信賬號作為網頁賬號

獲取用戶信息成功后直接跳轉到目標頁面即可

微信賬號和網站賬號進行綁定

思路:
01 獲取用戶信息成功
02 根據用戶openid到數據庫中去查找網頁賬號信息
03 如果查找到信息就說明已經綁定,直接跳轉拿到目標頁面即可
04 如果沒有獲取到就跳轉到登錄綁定頁面
05 用戶輸入賬號和密碼並提交到開發者后台
06 后台需對網站賬號合法性進行校驗
07 校驗通過后進行綁定操作
08 跳轉到目標頁面
代碼片段一

    /**
     * 回調頁面
     * @param map
     * @return
     */
    @GetMapping(value = "/callback")
    public String callback(ModelMap map, HttpServletRequest request, HttpServletResponse response) {
        log.info("進入回調處理邏輯......");
        String appid = weixinBaseInfoProperties.getAppid();
        String appsecret = weixinBaseInfoProperties.getAppsecret();

//        微信網頁授權第二步 - 通過code換取網頁授權access_token - start
        StringBuffer requestURL = request.getRequestURL();
        log.info("進入回調處理邏輯的請求url為:" + requestURL);
        String code = request.getParameter("code");
        log.info("獲取到的用於換取access_token的票據的code值為:" + code);

        String getAccessTokenUrl = weixinBaseInfoProperties.getAuth().getGetAccessTokenUrl();
        getAccessTokenUrl = getAccessTokenUrl.replace("APPID", appid)
                .replace("SECRET", appsecret)
                .replace("CODE", code);
        log.info("封裝好的用於獲取accessToke的url為:" + getAccessTokenUrl);
        String getAccessTokenResponseStr = httpUtils.doGetStrByRestTemplate(getAccessTokenUrl);
        log.info("發送獲取access_token請求后的響應為STR:" + getAccessTokenResponseStr);
        GetAuthAccessTokenResponse getAuthAccessTokenResponse = transformerUtils.String2Object(getAccessTokenResponseStr, GetAuthAccessTokenResponse.class);
        log.info("發送獲取access_token請求后的響應為:" + getAuthAccessTokenResponse);
        String access_token = getAuthAccessTokenResponse.getAccess_token();
        String open_id = getAuthAccessTokenResponse.getOpenid();
//        微信網頁授權第二步 - 通過code換取網頁授權access_token - end

//        微信網頁授權第四步 - 拉取用戶信息(需scope為 snsapi_userinfo) - start
        String getUserInfoUrl = weixinBaseInfoProperties.getAuth().getGetUserInfoUrl();
        getUserInfoUrl = getUserInfoUrl.replace("ACCESS_TOKEN", access_token)
                .replace("OPENID", open_id);
        log.info("封裝好的用於獲取userInfo的url為:" + getUserInfoUrl);
        String getUserInfoResponseStr = httpUtils.doGetStrByRestTemplate(getUserInfoUrl);
        log.info("發送獲取userInfo請求后的響應為STR:" + getUserInfoResponseStr);
        GetUserInfoResponse getUserInfoResponse = transformerUtils.String2Object(getUserInfoResponseStr, GetUserInfoResponse.class);
        log.info("發送獲取userInfo請求后的響應為:" + getUserInfoResponse);
//        微信網頁授權第四步 - 拉取用戶信息(需scope為 snsapi_userinfo) - end

//        第一種使用:直接使用微信的用戶用戶體系
//        map.addAttribute("userinfo", getUserInfoResponse);
//        return "index2";

//        第二種:微信用戶和網站用戶進行綁定
//        根據openid查詢網站的賬戶信息
        UserBindDO userBindDOByOpenid = userBindRepository.findByOpenid(getUserInfoResponse.getOpenid());
        if (userBindDOByOpenid != null) {
//            已經綁定過的情況
            log.info("已經綁定過啦");
            map.addAttribute("userinfo", userBindDOByOpenid);
            return "index3";
        } else {
//            沒有綁定過的情況
            log.info("還未進行綁定操作");
            map.addAttribute("openid", getUserInfoResponse.getOpenid());
            map.addAttribute("nickname", getUserInfoResponse.getNickname());
            return "login";
        }
    }

代碼片段二

    @PostMapping(value = "/login")
    public String login(UserBindDO userBindDO, ModelMap map) {
        log.info("獲取到的參數信息為:" + userBindDO);
//        TODO: 對賬戶信息進行格式校驗,如果格式不正確直接返回登錄綁定頁面
//        TODO: 驗證賬戶是否存在, 如果不存在直接跳轉到注冊頁面(微信用戶信息同時返回),在注冊邏輯中直接進行綁定
//        TODO: 驗證賬戶密碼是否正確,如果部正確直接返回登錄綁定頁面
        UserBindDO save = userBindRepository.save(userBindDO);
        if (save != null) {
            log.info("bind - 綁定成功");
            log.info("綁定后的結果信息為:" + save);
            map.addAttribute("userinfo", save);
            return "index3";
        } else {
            log.info("bind - 綁定失敗");
            return "login";
        }
    }

源代碼

  掃碼獲取


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM