微信公衆號03 微信網頁受權

前提準備

域名

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

我的訂閱號

因爲是進行微信網頁受權,因此須要一個我的微信訂閱號做爲開發基礎。
福利:因爲微信我的訂閱號沒有提供微信網頁受權功能,可是能夠利用微信提供的測試號進行開發。
測試號在哪裏:登陸我的訂閱號 -> 開發 -> 開發者工具 -> 公衆平臺測試帳號
注意:整個開發過程當中都是使用測試號的appID和appsecret數據庫

開發環境

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

微信網頁受權官方文檔

文檔路徑

文檔在哪裏:登陸微信訂閱號 -> 開發 -> 開發者工具 -> 開發文檔 -> 微信網頁開發 -> 微信網頁受權瀏覽器

回調域名配置

在哪裏配置:登陸我的訂閱號 -> 開發 -> 開發者工具 -> 公衆平臺測試帳號 -> 網頁服務 -> 網頁帳號 -> 修改 -> 填入受權回調頁面域名便可(推薦使用natapp)服務器

開發步驟

1 第一步:用戶贊成受權,獲取code
2 第二步:經過code換取網頁受權access_token
3 第三步:刷新access_token(若是須要)
4 第四步:拉取用戶信息(需scope爲 snsapi_userinfo)
5 附:檢驗受權憑證(access_token)是否有效微信

Java代碼實現

進入微信受權頁面

只須要經過微信瀏覽器訪問到微信受權的頁面便可。
思路
01 用戶經過微信瀏覽器進入一個頁面
02 點擊一個按鈕向開發者後臺發送一個GET請求
03 開發這個後臺封裝一個URL並重定向到這個URL
代碼片斷app

    /**
     * 微信網頁受權邏輯入口
     * @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";
        }
    }

源代碼

  掃碼獲取

相關文章
相關標籤/搜索