SoringCloud(四) - 微信获取用户信息

打印 上一主题 下一主题

主题 541|帖子 541|积分 1623

1、项目介绍


2、微信公众平台 和 微信开放文档

2.1 微信公众平台

2.1.1 网址链接

https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
2.1.2 测试号信息


2.1.3 微信扫描关注测试公众号


2.1.4 授权回调页面域名

2.1.4.1 网页服务->网页账号->修改


2.1.4.2 填写 授权回调页面域名


2.1.4.3 内网穿透 NATAPP

2.1.4.3.1 使用教程
  1. NATAPP1分钟快速新手图文教程: https://natapp.cn/article/natapp_newbie
  2. 下载: https://natapp.cn/#download
  3. 使用本地配置文件config.ini: https://natapp.cn/article/config_ini
复制代码
2.1.4.3.2 authtoken


2.1.4.3.3  授权回调页面域名


2.2  微信开放文档

2.2.1 网址链接

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#2
2.2.2 官方 基本步骤教程

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

3、http请求工具类 HttpClient4Util

HttpClient4Util 用来发http请求;
https://www.cnblogs.com/xiaoqigui/p/16839536.html
4、配置文件 和 配置类

4.1 配置文件

application.yml
  1. #端口
  2. server:
  3.   port: 8096
  4. # 自定义微信授权信息
  5. wechat:
  6.   auth:
  7.     app-id: wxd4e20add67******   #  appID
  8.     app-secret: a21e97d21d0d6ce408b7a6c******  # appsecret
  9.     code-uri: https://open.weixin.qq.com/connect/oauth2/authorize  # 请求微信官方获取用户授权code 的请求地址
  10.     redirect-uri: http://******.natappfree.cc/wechat/auth/codeBack # 微信官方返回  用户授权code 的回调地址
  11.     access-token-uri: https://api.weixin.qq.com/sns/oauth2/access_token # 根据微信回调的code值,请求微信官方获取用户access_token  的请求地址
  12.     user-info-uri: https://api.weixin.qq.com/sns/userinfo #根据用户的 accessToken 和  openId 拉取用户信息  的请求地址
复制代码
4.2 配置类
  1. //自定义微信授权参数信息配置类
  2. @Data
  3. @Component
  4. @ConfigurationProperties(prefix = "wechat.auth")
  5. public class WeChatAuthConfig {
  6.     /*
  7.         应用id
  8.      */
  9.     private String appId;
  10.     /*
  11.         应用密钥
  12.      */
  13.     private String appSecret;
  14.     /*
  15.         请求获取code的地址
  16.      */
  17.     private String codeUri;
  18.     /*
  19.         微信官方回调code的地址
  20.      */
  21.     private String redirectUri;
  22.     /**
  23.      * 微信官方获取access_token地址
  24.      */
  25.     private String accessTokenUri;
  26.     /*
  27.         微信官方获取userInfo地址
  28.      */
  29.     private String userInfoUri;
  30. }
复制代码
5、server 层

5.1 接口
  1. /**
  2. * Created On : 28/10/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 微信授权的业务接口
  7. */
  8. public interface WeChatAuthService {
  9.     /**
  10.      * @author : huayu
  11.      * @date   : 28/10/2022
  12.      * @param  : []
  13.      * @return : java.lang.String
  14.      * @description : 生成请求微信官方获取用户授权code的请求地址
  15.      */
  16.     String generateWeChatAuthCodeUrl();
  17.     /**
  18.      * @author : huayu
  19.      * @date   : 28/10/2022
  20.      * @param  : [wechatAuthCode]
  21.      * @return : java.lang.String
  22.      * @description : 根据微信回调的code值,请求微信官方获取用户access_token
  23.      */
  24.     String getAccessTokenFromWechatUseCode(String wechatAuthCode);
  25.     /**
  26.      * @author : huayu
  27.      * @date   : 28/10/2022
  28.      * @param  : [accessToken, openId]
  29.      * @return : java.lang.String
  30.      * @description : 根据用户的 accessToken 和  openId 拉取用户信息
  31.      */
  32.     String getUserInfoFromWechatUseAccessToken(String accessToken,String openId);
  33. }
复制代码
5.2 实现类
  1. /**
  2. * Created On : 28/10/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 微信授权的业务接口 实现类
  7. */
  8. @Service
  9. @Slf4j
  10. public class WeChatAuthServiceImpl implements WeChatAuthService{
  11.     @Autowired
  12.     private WeChatAuthConfig weChatAuthConfig;
  13.     /**
  14.      * @author : huayu
  15.      * @date   : 29/10/2022
  16.      * @param  : []
  17.      * @return : java.lang.String
  18.      * @description : 生成请求微信官方获取用户授权code的请求地址
  19.      */
  20.     @Override
  21.     public String generateWeChatAuthCodeUrl() {
  22.         //微信官方引导用户打开授权页面,获取code的完整路径
  23.         //https://open.weixin.qq.com/connect/oauth2/authorize
  24.         // ?appid=APPID
  25.         // &redirect_uri=REDIRECT_URI
  26.         // &response_type=code
  27.         // &scope=SCOPE
  28.         // &state=STATE
  29.         // #wechat_redirect
  30.         //尤其注意:由于授权操作安全等级较高,所以在发起授权请求时,微信会对授权链接做正则强匹配校验,如果链接的参数顺序不对,授权页面将无法正常访问
  31.         //生成请求卫星官方获取用户code的完整地址
  32.         StringBuilder weCharAuthCodeUrl = new StringBuilder(weChatAuthConfig.getCodeUri());
  33.         weCharAuthCodeUrl.append("?appid=").append(weChatAuthConfig.getAppId())
  34.                 .append("&redirect_uri=").append(weChatAuthConfig.getRedirectUri())
  35.                 .append("&response_type=code")
  36.                 //&scope=snsapi_userinfo&state=STATE
  37.                 .append("&scope=").append("snsapi_userinfo")
  38.                 .append("&state=").append("kh96_wechat_auth")
  39.                 .append("#wechat_redirect");
  40.         log.info("------ 请求微信官方授权网站地址:{}  ------",weCharAuthCodeUrl.toString());
  41.         //返货完整的请求地址
  42.         return weCharAuthCodeUrl.toString();
  43.     }
  44.     /**
  45.      * @author : huayu
  46.      * @date   : 29/10/2022
  47.      * @param  : [wechatAuthCode]
  48.      * @return : java.lang.String
  49.      * @description : 根据微信回调的code值,请求微信官方获取用户access_token
  50.      */
  51.     @Override
  52.     public String getAccessTokenFromWechatUseCode(String wechatAuthCode) {
  53.         // 尤其注意:由于公众号的 secret 和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。
  54.         // 请求方法:获取 code 后,请求以下链接获取access_token:
  55.         // https://api.weixin.qq.com/sns/oauth2/access_token
  56.         // ?appid=APPID
  57.         // &secret=SECRET
  58.         // &code=CODE
  59.         // &grant_type=authorization_code
  60.         // 封装根据code,请求微信官方获取access_token的完整地址
  61.         StringBuilder accessTokenUrl = new StringBuilder(weChatAuthConfig.getAccessTokenUri());
  62.         accessTokenUrl.append("?appid=").append(weChatAuthConfig.getAppId())
  63.                 .append("&secret=").append(weChatAuthConfig.getAppSecret())
  64.                 .append("&code=").append(wechatAuthCode)
  65.                 .append("&grant_type=authorization_code");
  66.         log.info("------ 根据code,请求微信官方获取access_token的完整地址:{} ------", accessTokenUrl.toString());
  67.         // 根据code,请求微信官方获取access_token,返回结果是同步返回的,不再是异步回调
  68.         // 请求是服务器内部发起的,也就是说:在程序中,要根据上面完整的请求地址,主动发送请求到微信官方,接口同步会返回一个json格式的字符串结果,程序内要解析获取的结果
  69.         // 程序内主动发起http请求,获取access_token
  70.         return HttpClient4Util.getResponse4GetAsString(accessTokenUrl.toString(), "utf-8");
  71.     }
  72.     /**
  73.      * @author : huayu
  74.      * @date   : 29/10/2022
  75.      * @param  : [accessToken, openId]
  76.      * @return : java.lang.String
  77.      * @description : 根据用户的 accessToken 和  openId 拉取用户信息
  78.      */
  79.     @Override
  80.     public String getUserInfoFromWechatUseAccessToken(String accessToken, String openId) {
  81.         // 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和 openid 拉取用户信息了。
  82.         // http:GET(请使用 https 协议):
  83.         // https://api.weixin.qq.com/sns/userinfo
  84.         // ?access_token=ACCESS_TOKEN
  85.         // &openid=OPENID
  86.         // &lang=zh_CN
  87.         // 封装根据accessToken和openId,请求微信官方获取用户信息详情地址
  88.         StringBuilder userInfoUrl = new StringBuilder(weChatAuthConfig.getUserInfoUri());
  89.         userInfoUrl.append("?access_token=").append(accessToken)
  90.                 .append("&openid=").append(openId)
  91.                 .append("&lang=zh_CN");
  92.         log.info("------ 根据access_token,请求微信官方获取userinfo的完整地址:{} ------", userInfoUrl.toString());
  93.         // 程序内主动发起http请求,获取用户详情
  94.         return HttpClient4Util.getResponse4GetAsString(userInfoUrl.toString(), "utf-8");
  95.     }
  96. }
复制代码
6、controller 层
  1. /**
  2. * Created On : 28/10/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 测试微信授权登录操作入口
  7. */
  8. //@SuppressWarnings("all")
  9. @Slf4j
  10. @RestController
  11. @RequestMapping("/wechat/auth")
  12. public class WeChatAuthController {
  13.     @Autowired
  14.     private WeChatAuthService weChatAuthService;
  15.     /**
  16.      * @author : huayu
  17.      * @date   : 28/10/2022
  18.      * @param  : []
  19.      * @return : com.kgc.scd.uitl.RequestResult<java.lang.String>
  20.      * @description :  获取请求微信官方货物code的完整地址,用户访问该地址,可以进行授权操作(把地址交给前端生成二维码给用户扫码,或者后端生成)
  21.      */
  22.     @GetMapping("/codeUrl")
  23.     public RequestResult<String> codeUrl(){
  24.         //调用业务接口,获取完整用户授权访问的地址
  25.         return ResultBuildUtil.success(weChatAuthService.generateWeChatAuthCodeUrl());
  26.     }
  27.     /**
  28.      * @author : huayu
  29.      * @date   : 28/10/2022
  30.      * @param  : []
  31.      * @return : com.kgc.scd.uitl.RequestResult<java.util.Map<java.lang.String,java.lang.Object>>
  32.      * @description : 接收微信官方一步回调请求,获取用户授权的code
  33.      * 流程:用户先根据上一步返回请求地址,进行授权操作,如果用户统一授权,微信官方自动根据上一步请求带过去的回调地址redirectUri,进行结果回调
  34.      */
  35.     @RequestMapping("/codeBack")
  36.     public RequestResult<Map<String, Object>> codeBack(HttpServletRequest request){
  37.         // 用户同意授权后,如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
  38.         // code说明:code作为换取access_token的票据,每次用户授权带上的 code 将不一样,code只能使用一次,5分钟未被使用自动过期。
  39.         // 从官方回调的请求中,获取用户授权后的code参数值
  40.         String wechatAuthCode = request.getParameter("code");
  41.         // 从官方回调的请求中,获取用户授权时的自定义参数state
  42.         String wechatAuthState = request.getParameter("state");
  43.         log.info("------ 微信授权后,官方异步回调结果:code={},state={} ------", wechatAuthCode, wechatAuthState);
  44.         // 定义接口返回集合对象
  45.         Map<String, Object> resultMap = new HashMap<>();
  46.         // 参数非空校验
  47.         if(StringUtils.isBlank(wechatAuthCode)){
  48.             resultMap.put("msg", "授权code为空!");
  49.             return ResultBuildUtil.fail(resultMap);
  50.         }
  51.         //  调用业务接口,通过 code 换取网页授权access_token
  52.         String accessTokenJson = weChatAuthService.getAccessTokenFromWechatUseCode(wechatAuthCode);
  53.         log.info("------ 通过 code 换取网页授权access_token返回结果:{} ------", accessTokenJson);
  54.         // 正确时返回的 JSON 数据包如下:
  55.         // {"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE"}
  56.         // 错误时返回的 JSON 数据包如下:
  57.         // {"errcode":40029,"errmsg":"invalid code"}
  58.         // 解析返回的json数据
  59.         JSONObject accessTokenJsonObj = JSON.parseObject(accessTokenJson);
  60.         // 判断获取access_token结果是否正确,如果错误,直接结束,如果正确,获取对应的access_token
  61.         if(StringUtils.isNotBlank(accessTokenJsonObj.getString("errcode"))){
  62.             resultMap.put("wxCode", accessTokenJsonObj.getString("errcode"));
  63.             resultMap.put("wxMsg", accessTokenJsonObj.getString("errmsg"));
  64.             return ResultBuildUtil.fail(resultMap);
  65.         }
  66.         // 拉取用户信息(需 scope 为 snsapi_userinfo)
  67.         // 根据上一步返回json,获取拉取用户信息凭证-access_token和用户唯一标识-openid
  68.         String accessToken = accessTokenJsonObj.getString("access_token");
  69.         String openId = accessTokenJsonObj.getString("openid");
  70.         //  调用业务接口,通过access_token和openId,拉取用户详情
  71.         String userInfoJson = weChatAuthService.getUserInfoFromWechatUseAccessToken(accessToken, openId);
  72.         log.info("------ 通过access_token和openId,拉取用户详情:{} ------", userInfoJson);
  73.         // 接口返回用户详情信息
  74.         resultMap.put("userInfo", userInfoJson);
  75.         // TODO 获取成功用户信息后,系统要完成静默注册-把用户信息注册到系统数据中,存储用户的头像,昵称,openId信息,并给系统用户表增加其它的基本信息
  76.         //返回用户详情
  77.         return ResultBuildUtil.success(resultMap);
  78.     }
  79. }
复制代码
7、测试

7.1  生成请求微信官方获取用户授权code的请求地址


7.2 获取用户信息






免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表