获取微信公众号openId

分为两步:

1. 获取code

2. 利用code获取openid 获取code时要提供redirect_uri,请求获取code的URL后会跳转到redirect_uri,在redirect_uri页面利用code获取openid

一、准备工作:

1. 申请公众号


申请公众号开发者账号:前往 微信公众平台 申请公众号开发者账号,并完成账号认证。

配置公众号开发设置:登录微信公众平台,在“开发-基本配置”中配置好公众号的相关信息,包括服务器配置、公众号名称、AppID、AppSecret等。

2. 申请小程序


申请小程序:前往 微信公众平台 | 小程序 申请小程序,具体可以按照页面引导操作

如果你已经认证了公众号,可以复用公众号的资质快速注册小程序,如下图所示:


 

二、实现:

工具类

@Slf4j
@Component
public class WeChatUtils {


    public static final String appid = WxPublicConfig.appId;

    public static final String secret = WxPublicConfig.secret;

    // 获取code
    public final static String CODE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";

    //获取网页access_token的接口地址
    public final static String WEB_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";


    //获取用户信息地址
    public final static String USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

    // 获取access_token的接口地址(GET) 限2000(次/天)
    public final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    // 发送模板消息
    public static final String SEND_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";


    /**
     * 生成获取code的url
     *
     * @param backUrl
     * @return
     */
    public String getCodeUrl(String backUrl, String state) {
        String requestUrl = null;
        state = state == null ? "" : state;
        try {
            requestUrl = CODE_URL.replace("APPID", appid).replace("REDIRECT_URI", URLEncoder.encode(backUrl, "UTF-8")).replace("STATE", state);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return requestUrl;
    }

    /**
     * 获取微信网页access_token 和 openid
     *
     * @param code
     * @return
     */
    public JSONObject getWebAccessTokenAndOpenid(String code) {
        String requestUrl = WEB_ACCESS_TOKEN_URL.replace("APPID", appid).replace("APPSECRET", secret).replace("CODE", code);
        return HttpUtils.httpPost(requestUrl, new JSONObject());
    }

    /**
     * 网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了
     * https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
     *
     * @param webAccessToken
     * @param openid
     * @return
     */
    public JSONObject getUserInfo(String webAccessToken, String openid) {
        String requestUrl = USERINFO_URL.replace("ACCESS_TOKEN", webAccessToken).replace("OPENID", openid);
        return HttpUtils.httpPost(requestUrl, new JSONObject());
    }

    public String getToken() {
        return getToken(null);
    }

    /**
     * 获取access_token 先从Redis获取,如果没有再调微信获取并存Redis
     *
     * @param forceRefresh 如果为“1”直接从微信获取并存Redis
     * @return
     */
    public String getToken(String forceRefresh) {

        String accessToken = null;
        String requestUrl = ACCESS_TOKEN_URL.replace("APPID", appid).replace("APPSECRET", secret);
        // 调用接口获取token
        JSONObject jsonObject = HttpUtils.httpPost(requestUrl, new JSONObject());
        // 如果请求成功//jsonObject.getString("errcode")
        if (null != jsonObject) {
            accessToken = jsonObject.getString("access_token");
        }
        log.debug("forceRefresh" + forceRefresh + "获取access_token:" + accessToken);
        return accessToken;
    }


}

链接解析:

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

appid:公众号的AppID
公众号的唯一标识,可以在公众号后台获取到AppID

redirect_uri:用户同意授权后的回调URL
授权后重定向的回调链接地址,需使用 urlEncode 对链接进行处理

response_type:返回类型,固定填写code

scope:应用授权作用域

snsapi_userinfo:固定值 ,表示获取用户信息的权限范围

snsapi_userinfo:弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息

state:自定义参数
重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节

#wechat_redirect:固定传递
必须带此参数

控制层

@RestController
@RequestMapping("/wx/public")
public class WxPublicController {
    @Resource
    WxPublicService wxPublicService;

    /**
     * 获取openId
     *
     * @param code
     * @return
     */
    @GetMapping("/getOpenId")
    @ResponseBody
    public ResultBean getOpenId(String code) {
        if (code == null || code.equals("")) {
            return ResultBean.error("未获取到code");
        }
        return wxPublicService.getOpenId(code);
    }
}

Service层

public interface WxPublicService {
    /**
     * 获取openId
     * @param code
     * @return
     */
    public ResultBean getOpenId(String code);
}
ServiceImpl层
@Service
public class WxPublicServiceImpl implements WxPublicService {
    @Resource
    WeChatUtils weChatUtils;

    @Override
    public ResultBean getOpenId(String code) {
        if (code == null) {
            return ResultBean.error("未获取到code");
        }
        JSONObject jsonObject = weChatUtils.getWebAccessTokenAndOpenid(code);
        if (jsonObject != null && jsonObject.size() > 0) {
            if (jsonObject.getString("errcode") == null) {
                String openId = jsonObject.getString("openid");
                String accessToken = jsonObject.getString("access_token");
                if (openId == null) {
                    ResultBean.error("未获取到openId");
                }
                return ResultBean.success(openId);
            } else {
                return ResultBean.error(jsonObject.getString("errmsg"));
            }
        } else {
            return ResultBean.error("未获取到信息");
        }
    }
}

三、遇到的问题

1. 如何调试

其实调试问题,微信官方也已经考虑到了这个问题,在微信公众号的后台,他们提供了一下开发者工具,可以让我们在开发阶段进行便捷的测试,如下图所示

在这里,我们主要使用的是 “公众平台测试账号” 这个工具,下面我们看一下这个工具是如何使用的。

  • 第一步

点击 “公众平台测试账号” ,用自己微信扫码进行登录,然后就进入到了主页,在主页中我们可以看到给我们生成了测试的 appID 和 appsecret,这两个重要的参数以供我们测试授权使用

  • 第二步

在当前页面中我们找到 “测试号二维码” 一栏,使用需要调试的微信扫码关注测试公众号,如下图所示:

  • 第三步

在当前页面继续向下滚动页面,找到 “网页授权获取用户基本信息”,点击修改,添加授权回调域名,如下图所示

完成上面的两步后,我们就可以进行愉快的测试了,可以使用手机微信,或者是微信开发者工具进行调试!

注意:调试阶段,可以使用域名或IP都可以,在正式上线环境下,必须使用备案的域名才可以!

2. redirect_uri
redirect_uri 必须提前在微信公众号后台中维护好授权回调域名,否则会报 “10003:redirect_uri域名与后台配置不一致”

redirect_uri 必须使用 urlEncode 进行编码处理

使用 Vue 框架开发的,建议使用 history 路由模式,可以避免微信回调链接的各种参数拼接问题

使用 Vue 开发时,如果你非要使用 hash 路由模式,也不是不可以解决,只能在路由拦截器中处理一下 # 拼接的问题,重新整理成正确的路由链接就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值