微信授权的整体思路:

1 第一步:用户同意授权,获取code
2 第二步:通过code换取网页授权access_token
3 第三步:刷新access_token(如果需要)
4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
5 附:检验授权凭证(access_token)是否有效

微信授权官方文档:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

代码实现:

package com.woyaoce.TencentApi.controller;


import com.alibaba.fastjson.JSONObject;
import com.woyaoce.TencentApi.constant.WxConstants;
import com.woyaoce.TencentApi.utils.HttpClientUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.util.Iterator;
import java.util.Map;

/**
 * 微信授权操作入口操作公共方法控制层
 *
 * @author madong
 */
@RestController
@RequestMapping("/wx")
public class WxAuthorizeController {

    private static final Logger logger = LoggerFactory.getLogger(WxAuthorizeController.class);

    // 0000-失败
    private final static String ERROR_CODE = "0000";

    @ApiOperation(value = "扫描裂变海报二维进入海报报名会议首页", notes = "扫描裂变海报二维进入海报报名会议首页")
    @RequestMapping(value = "/getCode")
    public void getCode(@RequestParam(value = "code") String code, HttpServletResponse response) {
        // 重定向地址 https://m.woyaoce.cn/special我的微信授权地址
        String redirect_uri = "https://m.woyaoce.cn/special/wx/getWxUserInfo?code=" + code;
        try {
            redirect_uri = URLEncoder.encode(redirect_uri, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 微信授权接口
        String getCodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + WxConstants.APPID +
                "&redirect_uri=" + redirect_uri +
                "&response_type=code&" +
                "scope=snsapi_userinfo&" +
                "state=STATE&connect_redirect=1#wechat_redirect";
        try {
            response.sendRedirect(getCodeUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 根据微信授权code拉取用户信息
     *
     * @param code 微信授权code
     */
    @ApiOperation(value = "根据微信授权code拉取用户信息", notes = "根据微信授权code拉取用户信息")
    @GetMapping(value = "/getWxUserInfo")
    @ResponseBody
    public String getWxUserInfo(@RequestParam @ApiParam(name = "code", value = "微信code", required = true) String code) {

        logger.info("成功进入,开始根据微信授权code拉取用户信息,code:{}", code);
        // 根据code调取微信获取用户信息的返回集
        String wxResult;
        String path = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WxConstants.APPID + "&secret=" + WxConstants.APP_SECRET + "&code=" + code + "&grant_type=authorization_code";
        // 重点:获取access_token,并判断返回值
        JSONObject obj = JSONObject.parseObject(HttpClientUtil.doGet(path));
        Iterator it =obj.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
            if("errcode".equals(entry.getKey())){
                return ERROR_CODE;
            }
            if("access_token".equals(entry.getKey())){
                break;
            }
        }

        //得到token
        String accessToken = (String) obj.get("access_token");
        logger.info("access_token:" + accessToken);
        //得到openid
        String openid = (String) obj.get("openid");
        //根据code值和oppenid获取用户的基本信息
        String path2 = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
        wxResult = HttpClientUtil.doGet(path2);
        logger.info("根据code调取微信获取用户信息的返回集wxResult:" + wxResult);
        return wxResult;

    }

}

代码真的不难,但是其中还是有很多坑的,比如在第二个方法getWxUserInfo()中获取access_token的时候,如果这块“JSONObject obj = JSONObject.parseObject(HttpClientUtil.doGet(path));”根据code调用实施失败或者获取不到access_token的话,他返回的是带有errcode的一个json数据;

{"errcode":"ox74s6K1jLNa3zlr4xvD0L0R5lA4",.....后面的json记不清了,错误返回肯定没有以access_token为key的数据}

但是如果正确返回,他返回的json数据是这样的:

{"access_token":"ox74s6K1jLNa3zlr4xvD0L0R5lA4",.....后面的json记不清了,大概是这个意思,反正是正确的返回没有以errcode为key的数据}

这时候为了程序的健壮性,你需要对结果集进行判断。如果返回结果集中包含errcode为主键的字符,那么说明调用失败,那么需要返回给其他调用服务一个错误代码(0000,这个错误代码随便定义),如果调用成功,那么返回的的肯定包含以access_token为key的数据,这样在继续调用微信获取用户信息的接口才能获取成功,最终调用获取用户信息接口成功返回的数据样例为:

{"openid":"ox74s6K1jLNa3zlr4xvD0L0R5lA4","nickname":"md","sex":1,"language":"zh_CN","city":"海淀","province":"北京","country":"中国","headimgurl":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTLs8SZLLWjyib3HtL1ZPZ76jpVZYiaRk2fpBPBqwwVcE1ZwLBF5cVbDKRF4vZVfnMRmjEq84I7fibH6g\/132","privilege":[],"unionid":"o_mJ01oKG8BPQZZsHpowTSp6uavQ"}

写这个整体思路还是很重要的,要理解:获取code然后授权(弹出授权页面)这一块不需要你用代码实现,而是调用微信接口,微信给你做!!!!!