SpringCloud Alibaba 开发微信公众号 (网页授权获取用户基本信息)

简介: SpringCloud Alibaba 开发微信公众号 (网页授权获取用户基本信息)

上一篇讲了模板消息管理,这一篇讲网页授权获取用户基本信息。

场景:

用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。

网页授权流程分为四步:
1.  引导用户进入授权页面同意授权,获取code
1.  通过 code 换取网页授权access_token(与基础支持中的access_token不同)
1.  如果需要,开发者可以刷新网页授权access_token,避免过期
1.  通过网页授权access_token和 openid 获取用户基本信息(支持 UnionID 机制)
复制代码

1 第一步:用户同意授权,获取code

首先需要引导用户点击授权链接,如果用户同意授权就可以拿到用户的code,进行下一步。

1.1 微信常量类新增设置引导链接URL OAUTH2_AUTHORIZE   ()

/**
 * 引导链接
 */
    public static final String OAUTH2_AUTHORIZE = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
复制代码

参数说明:

appid: 公众号的唯一标识

redirect_uri: 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理 (设置方式如图:

网络异常,图片无法展示
|

注意: 这块有个细节,如果设置错了1.2步骤回调时就汇报(10003 redirect_uri域名与后台配置不一致 ),一定是域名不要带着http:// 等协议头。见官文

网络异常,图片无法展示
|

网络异常,图片无法展示
|

response_type: 返回类型,请填写code

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

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

#wechat_redirect: 无论直接打开还是做页面302重定向时候,必须带此参数

1.2 修改文本消息处理类 TextMessageService

我们修改文本消息处理类,设置当用户文本为“授权登录”时,展示用户登录链接,用户点击链接则获取到用户的code

private final WeCharConfig weCharConfig;
public TextMessageService(WeCharConfig weCharConfig) {
    this.weCharConfig = weCharConfig;
}
@Override
public String handler(Map<String, Object> param) {
    String content = "你好呀,欢迎关注我的测试公众号!!";
    if (param.get(WeCharConstant.CONTENT).toString().equals("授权登录")) {
        content = WeCharConstant.OAUTH2_AUTHORIZE.replace("APPID", weCharConfig.getAppId())
                .replace("REDIRECT_URI", "https://6016a95m81.zicp.fun/v1/weChar/getCode").replace("SCOPE", "snsapi_userinfo");
        System.out.println(content);
        content = "您好,请点击<a href='" + content + "'>授权登录</a>进行更多的操作。";
    }
    return  TextMessage.ofSendMsg(param, content).toXml();
}
复制代码

1.3  增加回调处理类 UserInfoController

import cn.org.spring.common.util.HttpClientUtils;
import com.alibaba.fastjson.JSON;
import com.ctsi.sddx.config.WeCharConfig;
import com.ctsi.sddx.constants.WeCharConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/**
 * @Author : lizzu
 * @create 2022/10/5 16:05
 */
@Slf4j
@RestController
@RequestMapping("/v1/weChar")
public class UserInfoController {
    @Autowired
    private WeCharConfig charConfig;
    /**
     * 回调链接
     * 1、获取code -> 获取accessToken ->获取用户基本信息
     */
    @RequestMapping("/getCode")
    public String getCode(@RequestParam("code") String code,
                          @RequestParam("state") String state)  {
        System.out.println(code);
        System.out.println(state);
        return code+"----"+state;
    }
 }
复制代码

1.4 测试

网络异常,图片无法展示
|
成功取到用户code 后台输出

网络异常,图片无法展示
|

2 第二步:通过 code 换取网页授权access_token

2.1 微信常量类新增获取OAUTH认证的access_token URL OAUTH_GET_AT

/**
 * 获取OAUTH认证的access_token
 */
public static final String OAUTH_GET_AT = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
复制代码

2.2 修改 UserInfoController 回调方法getCode() ,增加获取accessToken 和 openID 方法getAccessToken(String code)

@Autowired
    private WeCharConfig charConfig;
    /**
     * 回调链接
     * 1、获取code -> 获取accessToken ->获取用户基本信息
     */
    @RequestMapping("/getCode")
    public String getCode(@RequestParam("code") String code,
                          @RequestParam("state") String state) throws IOException {
        System.out.println(code);
        System.out.println(state);
        String userInfo = getAccessToken(code);
        return userInfo;
    }
    /**
     * 获取accessToken 和 openID
     *
     * @param code
     * @return
     * @throws IOException
     */
    public String getAccessToken(String code) throws IOException {
        String s = HttpClientUtils.get(WeCharConstant.OAUTH_GET_AT.replace("APPID", charConfig.getAppId())
                .replace("SECRET", charConfig.getSecret()).replace("CODE", code));
        System.out.println("获取access token " + s);
        String access_token = JSON.parseObject(s).getString("access_token");
        String openid = JSON.parseObject(s).getString("openid");
        return "access_token:"+access_token+" openid:"+openid;
    }
复制代码

2.3 测试:

获取access token {"access_token":"61_ZumbIGiicy0Efksa3Ru5doVykU-qWCqFRf8EbWh8nHEstNhq6qV-5YRnc38X8Zf4gjyIY3BblJ0MVaTLW68MoB75UuKPp7S-cFa9omcgm7M","expires_in":7200,"refresh_token":"61_Y62Fo2Bdxp3U0fYkgPjTFMBNqU1073xikXko8eYq904qVUPiJfj3UmxJt76u4aEib1HfQLUmBdxrBUVigxK5Sa5xTvc8-j7VBrELaxfhLdM","openid":"oITpR58LM-HJG0Fa4BY6MkOCG5lM","scope":"snsapi_userinfo"}
格式化:
{
  "access_token": "61_ZumbIGiicy0Efksa3Ru5doVykU-qWCqFRf8EbWh8nHEstNhq6qV-5YRnc38X8Zf4gjyIY3BblJ0MVaTLW68MoB75UuKPp7S-cFa9omcgm7M",
  "expires_in": 7200,
  "refresh_token": "61_Y62Fo2Bdxp3U0fYkgPjTFMBNqU1073xikXko8eYq904qVUPiJfj3UmxJt76u4aEib1HfQLUmBdxrBUVigxK5Sa5xTvc8-j7VBrELaxfhLdM",
  "openid": "oITpR58LM-HJG0Fa4BY6MkOCG5lM",
  "scope": "snsapi_userinfo"
}
复制代码

可以看到已经拿到了access_token,有效期expires_in、刷新token refresh_token 等。

3 第三步:刷新access_token(如果需要)

如果超时,即可使用

**请求方法**
> 获取第二步的refresh_token后,请求以下链接获取access_token:
> https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
复制代码

4 第四步:拉取用户信息(需 scope 为 snsapi_userinfo)

4.1微信常量类新增获取用户基本信息 URL OAUTH_USER_INFO

/**
 * 获取用户基本信息
 */
public static final String OAUTH_USER_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
复制代码

4.2修改 UserInfoController 增加获取用户基本信息方法 getUserInfo

/**
 * 获取用户基本信息
 *
 * @param accessToken
 * @param openId
 * @return
 * @throws IOException
 */
public String getUserInfo(String accessToken, String openId) throws IOException {
    return HttpClientUtils.get(WeCharConstant.OAUTH_USER_INFO.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId));
}
复制代码

4.3测试

网络异常,图片无法展示
|

格式化数据
{
  "openid": "oITpR58LM-HJG0Fa4BY6MkOCG5AA",
  "nickname": "? 奇了怪了怪",
  "sex": 0,
  "language": "",
  "city": "",
  "province": "",
  "country": "",
  "headimgurl": "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoNc4aUZJT2w05SMIqFLQLxofkjuADnj3icyeIiaNDVlxKbFfkQRDchfwYI3FQTdxPu0NDGBSBUzVqg/135",
  "privilege": []
}
复制代码

5 附:检验授权凭证(access_token)是否有效

5.1 微信常量类新增获取用户基本信息 URL OAUTH_USER_INFO

/**
 * 获取用户基本信息
 */
public static final String CHECK_USER_INFO = "https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID";
复制代码

5.2 UserInfoController 新增检验授权凭证(access_token)是否有效方法 checkAccessToken(String accessToken, String openId)

完整UserInfoController

import cn.org.spring.common.util.HttpClientUtils;
import com.alibaba.fastjson.JSON;
import com.ctsi.sddx.config.WeCharConfig;
import com.ctsi.sddx.constants.WeCharConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/**
 * @Author : lizzu
 * @create 2022/10/5 16:05
 */
@Slf4j
@RestController
@RequestMapping("/v1/weChar")
public class UserInfoController {
    @Autowired
    private WeCharConfig charConfig;
    /**
     * 回调链接
     * 1、获取code -> 获取accessToken ->获取用户基本信息
     */
    @RequestMapping("/getCode")
    public String getCode(@RequestParam("code") String code,
                          @RequestParam("state") String state) throws IOException {
        System.out.println(code);
        System.out.println(state);
        String userInfo = getAccessToken(code);
        log.info("获取用户的基本信息 【{}】", userInfo);
        return userInfo;
    }
    /**
     * 获取accessToken 和 openID
     *
     * @param code
     * @return
     * @throws IOException
     */
    public String getAccessToken(String code) throws IOException {
        String s = HttpClientUtils.get(WeCharConstant.OAUTH_GET_AT.replace("APPID", charConfig.getAppId())
                .replace("SECRET", charConfig.getSecret()).replace("CODE", code));
        System.out.println("获取access token " + s);
        String access_token = JSON.parseObject(s).getString("access_token");
        String openid = JSON.parseObject(s).getString("openid");
        checkAccessToken(access_token, openid);//检验授权凭证(access_token)是否有效
        return getUserInfo(access_token, openid);
    }
    /**
     * 获取用户基本信息
     *
     * @param accessToken
     * @param openId
     * @return
     * @throws IOException
     */
    public String getUserInfo(String accessToken, String openId) throws IOException {
        return HttpClientUtils.get(WeCharConstant.OAUTH_USER_INFO.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId));
    }
    /**
     * 检验授权凭证(access_token)是否有效
     *
     * @param accessToken
     * @param openId
     * @return
     * @throws IOException
     */
    public String checkAccessToken(String accessToken, String openId) throws IOException {
        String s = HttpClientUtils.get(WeCharConstant.CHECK_USER_INFO.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId));
        String errmsg = JSON.parseObject(s).getString("errmsg");
        log.info("校验结果: 【{}】", errmsg);
        return s;
    }
}
复制代码

5.3测试:

网络异常,图片无法展示
|

至此网页授权获取用户基本信息相关接口的代码实现已完成

下一篇: 本想着找个实战的结果没找到....就先欠着下一篇写小程序的吧。


相关文章
|
12天前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
|
1月前
|
小程序 JavaScript API
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
这篇文章介绍了使用uni-halo框架进行微信小程序开发的过程,包括选择该框架的原因、开发目标以及项目配置和部署的步骤。
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
|
4月前
|
小程序 前端开发 Android开发
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
1052 29
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
|
3月前
|
监控 数据可视化 数据处理
微信养号脚本,全自动插件,AUTOJS开发版
这是一套自动化微信养号工具,包含主脚本`wechat_auto.js`与配置文件`config.json`。主脚本实现自动浏览朋友圈、随机阅读订阅号文章及搜索指定公众号三大功能,支持自定义滚动次数、阅读时长等参数。代码通过随机化操作间隔模拟真实用户行为,具备完善的错误处理和日志记录功能。配套UI模块提供可视化操作界面,可实时监控任务状态与运行日志,便于调整参数设置。控制器部分扩展了批量数据处理能力,如学生信息的增删改查操作,适用于多场景应用。下载地址:https://www.pan38.com/share.php?code=n6cPZ 提取码:8888(仅供学习参考)。
|
5月前
|
小程序 Java 关系型数据库
weixin163基于微信小程序的校园二手交易平台系统设计与开发ssm(文档+源码)_kaic
本文介绍了一款基于微信小程序的校园二手物品交易平台的开发与实现。该平台采用Java语言开发服务端,使用MySQL数据库进行数据存储,前端以微信小程序为载体,支持管理员和学生两种角色操作。管理员可管理用户、商品分类及信息、交易记录等,而学生则能注册登录、发布购买商品、参与交流论坛等。系统设计注重交互性和安全性,通过SSM框架优化开发流程,确保高效稳定运行,满足用户便捷交易的需求,推动校园资源共享与循环利用。
|
6月前
|
人工智能 自然语言处理 小程序
技术小白如何利用DeepSeek半小时开发微信小程序?
通过通义灵码的“AI程序员”功能,即使没有编程基础也能轻松创建小程序或网页。借助DeepSeek V3和R1满血版模型,用户只需用自然语言描述需求,就能自动生成代码并优化程序。例如,一个文科生仅通过描述需求就成功开发了一款记录日常活动的微信小程序。此外,通义灵码还提供智能问答模式,帮助用户解决开发中的各种问题,极大简化了开发流程,让普通人的开发体验更加顺畅。
1926 11
技术小白如何利用DeepSeek半小时开发微信小程序?
|
5月前
|
小程序 关系型数据库 Java
weixin168“返家乡”高校暑期社会实践微信小程序设计与开发ssm(文档+源码)_kaic
本文探讨高校暑期社会实践微信小程序的开发与应用,旨在通过信息化手段提升活动管理效率。借助微信小程序技术、SSM框架及MySQL数据库,实现信息共享、流程规范和操作便捷。系统涵盖需求分析、可行性研究、设计实现等环节,确保技术可行、操作简便且经济合理。最终,该小程序可优化活动发布、学生信息管理和心得交流等功能,降低管理成本并提高工作效率。
|
6月前
|
小程序 JavaScript 前端开发
微信小程序开发全流程:从注册到上线的完整指南
这篇文章详细记录了微信小程序的完整开发到最终上线的每一个步骤。适合对小程序开发感兴趣的个人开发者或希望了解完整流程的学习者,涵盖了云开发、事件绑定、生命周期管理、组件使用等关键内容。
2138 11
|
6月前
|
负载均衡 Dubbo Java
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
|
6月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
122 0