SpringCloud : 接入 微信公眾號平台(二)、菜單跳轉auth2.0授權


 

大概流程:

1. 通過 https://域名/auth/getOauthUrl 獲取到auth2.0的授權跳轉地址(也就是微信公眾號跳轉菜單綁定的鏈接)。

如何添加菜單請參考代碼:WxMenuController.java

核心代碼就是 wxMpService.oauth2buildAuthorizationUrl("處理授權回調的url", WxConsts.OAuth2Scope.SNSAPI_USERINFO, this.urlEncode("目標鏈接"));

 

2. 然后訪問該鏈接,微信為彈出一個確認授權彈窗,用戶確認通過之后,會跳轉到 https://域名/auth/callback 處理微信授權回調。 

 

 

3. 然后callback 方法處理完畢后,再重定向到你需要重定向的目標鏈接。

 

import com.phpdragon.wechat.proxy.config.WeChatConfig;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

/**
 * 處理微信auth2.0授權
 */
@Slf4j
@RequestMapping("/auth/")
@RestController
public class AuthController {

    @Autowired
    private WeChatConfig weChatConfig;

    /**
     * 返回授權地址,用於微信中用戶再次確認授權
     * 參考:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
     *
     * @param appId
     * @param redirectUrl
     * @return
     */
    @ResponseBody
    @GetMapping("/getOauthUrl")
    public String getOauthUrl(@RequestParam("app_id") String appId, @RequestParam("redirect_url") String redirectUrl) {
        String localAuthHandleUrl = this.getLocalAuthHandleUrl(appId);
        WxMpService wxMpService = weChatConfig.getWxMpService(appId);
        String oauthUrl = wxMpService.oauth2buildAuthorizationUrl(localAuthHandleUrl, WxConsts.OAuth2Scope.SNSAPI_USERINFO, this.urlEncode(redirectUrl));
        log.info("【微信網頁授權】獲取code,oauthUrl={}", oauthUrl);
        return oauthUrl;
    }

    /**
     * 構造授權地址,並直接重定向,用於微信中用戶再次確認授權
     * 參考:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
     *
     * @param appId
     * @param redirectUrl
     * @return
     */
    @GetMapping("/redirectOauthUrl")
    public RedirectView redirectAuthorizeUrl(@RequestParam("app_id") String appId, @RequestParam("redirect_url") String redirectUrl) {
        String localAuthHandleUrl = this.getLocalAuthHandleUrl(appId);
        WxMpService wxMpService = weChatConfig.getWxMpService(appId);
        String oauthUrl = wxMpService.oauth2buildAuthorizationUrl(localAuthHandleUrl, WxConsts.OAuth2Scope.SNSAPI_USERINFO, this.urlEncode(redirectUrl));
        log.info("【微信網頁授權】獲取code,oauthUrl={}", oauthUrl);
        return new RedirectView(oauthUrl);
    }

    /**
     * 處理微信授權回調
     * 參考:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
     *
     * @param code
     * @param returnUrl
     * @return
     * @throws Exception
     */
    @GetMapping("/callback/{app_id}")
    public RedirectView callback(@PathVariable("app_id") String appId,
                                  @RequestParam("code") String code,
                                  @RequestParam("state") String returnUrl) throws Exception {
        log.info("【微信網頁授權】code={}", code);
        log.info("【微信網頁授權】state={}", returnUrl);

        WxMpService wxMpService = weChatConfig.getWxMpService(appId);

        WxMpOAuth2AccessToken wxMpOauth2AccessToken;
        try {
            //獲取access_token
            wxMpOauth2AccessToken = wxMpService.oauth2getAccessToken(code);
        } catch (WxErrorException e) {
            log.info("微信網頁授權,error:{},{}", e.getMessage(), e);
            throw new Exception(e.getError().getErrorMsg());
        }

        String openId = wxMpOauth2AccessToken.getOpenId();
        log.info("【微信網頁授權】openId={}", openId);

        //這里的access-token是個人的,不是全局那個access-token,不能全局共享
        //獲得用戶基本信息
        //WxMpUser mpUser = wxMpService.oauth2getUserInfo(wxMpOauth2AccessToken, null);
        //log.info("【微信網頁授權】用戶信息={}", JSONObject.toJSONString(mpUser));

        //如果有配置動態獲取授權跳轉地址,則使用,否則使用菜單中默認配置好的跳轉地址
        String redirectUrl = this.getOauthRedirectUrl(appId, openId);
        if (StringUtils.isBlank(redirectUrl)) {
            Map<String, String> params = new HashMap<>(2);
            params.put("openid", openId);
            params.put("app_id", appId);
            redirectUrl = this.appendParam(returnUrl, params);
        }

        return new RedirectView(redirectUrl);
    }

    /**
     * 獲取授權通過后重定向后的地址
     *
     * @param appId
     * @param openId
     * @return
     */
    @Nullable
    private String getOauthRedirectUrl(String appId, String openId) {
        //TODO: 實現調轉地址的db化
        return "http://www.baidu.com";
    }

    /**
     * 獲取本地授權地址
     *
     * @return
     */
    private String getLocalAuthHandleUrl(String appId) {
        return WeChatConfig.CURRENT_HOST + "/auth/callback/" + appId;
    }

    private String urlEncode(String str) {
        try {
            return URLEncoder.encode(str, "utf8");
        } catch (Exception var3) {
            return str;
        }
    }

    private String appendParam(String originUrl, Map<String, String> appendParams) {
        URL url = newUrl(originUrl);
        if (Objects.isNull(url)) {
            return "";
        } else {
            StringBuilder sb = new StringBuilder(url.getProtocol());
            sb.append("://");
            sb.append(url.getHost());
            if (url.getPort() > -1) {
                sb.append(":");
                sb.append(url.getPort());
            }

            sb.append(url.getPath());
            sb.append("?");
            if (StringUtils.isNoneBlank(new CharSequence[]{url.getQuery()})) {
                String[] queryArr = StringUtils.split(url.getQuery(), "&");
                Map<String, String> params = new LinkedHashMap(queryArr.length);
                String[] var6 = queryArr;
                int var7 = queryArr.length;

                for (int var8 = 0; var8 < var7; ++var8) {
                    String item = var6[var8];
                    if (StringUtils.isNoneBlank(new CharSequence[]{item})) {
                        String[] itemArr = StringUtils.split(item, "=");
                        params.put(itemArr[0], itemArr[1]);
                    }
                }

                params.putAll(appendParams);
                sb.append(this.buildQuery(params));
            } else {
                sb.append(this.buildQuery(appendParams));
            }

            if (StringUtils.isNoneBlank(new CharSequence[]{url.getRef()})) {
                sb.append("#");
                sb.append(url.getRef());
            }

            return sb.toString();
        }
    }

    private String buildQuery(Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        int total = params.size();
        Iterator var3 = params.entrySet().iterator();

        while (var3.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry) var3.next();
            --total;
            sb.append((String) entry.getKey());
            sb.append("=");
            sb.append((String) entry.getValue());
            if (total > 0) {
                sb.append("&");
            }
        }

        return sb.toString();
    }

    private URL newUrl(String url) {
        try {
            return new URL(url);
        } catch (MalformedURLException var2) {
            log.error("實例化URI失敗,error:{},{}", var2.getMessage(), var2);
            return null;
        }
    }
}

 

 

 

PS:

公眾號開發文檔wiki

Java開發微信公眾號之整合weixin-java-tools框架開發微信公眾號

從零實現 Spring Boot 2.0 整合 weixin-java-mp(weixin-java-tools) 獲取 openId,用於微信授權

 

Demo 列表

  1. 微信支付 Demo:GitHub碼雲
  2. 企業號/企業微信 Demo:GitHub碼雲
  3. 微信小程序 Demo:GitHub碼雲
  4. 開放平台 Demo:GitHub碼雲
  5. 公眾號 Demo:
    • 使用 Spring MVC 實現的公眾號 Demo:GitHub碼雲
    • 使用 Spring Boot 實現的公眾號 Demo(支持多公眾號):GitHub碼雲
    • 含公眾號和部分微信支付代碼的 Demo:GitHub碼雲

 


免責聲明!

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



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