SoringCloud(四) - 微信获取用户信息
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 使用教程
NATAPP1分钟快速新手图文教程: https://natapp.cn/article/natapp_newbie
下载: https://natapp.cn/#download
使用本地配置文件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请求;
4、配置文件 和 配置类
4.1 配置文件
application.yml
#端口
server:
port: 8096
# 自定义微信授权信息
wechat:
auth:
app-id: wxd4e20add67****** # appID
app-secret: a21e97d21d0d6ce408b7a6c****** # appsecret
code-uri: https://open.weixin.qq.com/connect/oauth2/authorize # 请求微信官方获取用户授权code 的请求地址
redirect-uri: http://******.natappfree.cc/wechat/auth/codeBack # 微信官方返回 用户授权code 的回调地址
access-token-uri: https://api.weixin.qq.com/sns/oauth2/access_token # 根据微信回调的code值,请求微信官方获取用户access_token 的请求地址
user-info-uri: https://api.weixin.qq.com/sns/userinfo #根据用户的 accessToken 和 openId 拉取用户信息 的请求地址
4.2 配置类
//自定义微信授权参数信息配置类
@Data
@Component
@ConfigurationProperties(prefix = "wechat.auth")
public class WeChatAuthConfig {
/*
应用id
*/
private String appId;
/*
应用密钥
*/
private String appSecret;
/*
请求获取code的地址
*/
private String codeUri;
/*
微信官方回调code的地址
*/
private String redirectUri;
/**
* 微信官方获取access_token地址
*/
private String accessTokenUri;
/*
微信官方获取userInfo地址
*/
private String userInfoUri;
}
5、server 层
5.1 接口
/**
* Created On : 28/10/2022.
*
* Author : huayu
*
* Description: 微信授权的业务接口
*/
public interface WeChatAuthService {
/**
* @author : huayu
* @date : 28/10/2022
* @param : []
* @return : java.lang.String
* @description : 生成请求微信官方获取用户授权code的请求地址
*/
String generateWeChatAuthCodeUrl();
/**
* @author : huayu
* @date : 28/10/2022
* @param : [wechatAuthCode]
* @return : java.lang.String
* @description : 根据微信回调的code值,请求微信官方获取用户access_token
*/
String getAccessTokenFromWechatUseCode(String wechatAuthCode);
/**
* @author : huayu
* @date : 28/10/2022
* @param : [accessToken, openId]
* @return : java.lang.String
* @description : 根据用户的 accessToken 和 openId 拉取用户信息
*/
String getUserInfoFromWechatUseAccessToken(String accessToken,String openId);
}
5.2 实现类
/**
* Created On : 28/10/2022.
*
* Author : huayu
*
* Description: 微信授权的业务接口 实现类
*/
@Service
@Slf4j
public class WeChatAuthServiceImpl implements WeChatAuthService{
@Autowired
private WeChatAuthConfig weChatAuthConfig;
/**
* @author : huayu
* @date : 29/10/2022
* @param : []
* @return : java.lang.String
* @description : 生成请求微信官方获取用户授权code的请求地址
*/
@Override
public String generateWeChatAuthCodeUrl() {
//微信官方引导用户打开授权页面,获取code的完整路径
//https://open.weixin.qq.com/connect/oauth2/authorize
// ?appid=APPID
// &redirect_uri=REDIRECT_URI
// &response_type=code
// &scope=SCOPE
// &state=STATE
// #wechat_redirect
//尤其注意:由于授权操作安全等级较高,所以在发起授权请求时,微信会对授权链接做正则强匹配校验,如果链接的参数顺序不对,授权页面将无法正常访问
//生成请求卫星官方获取用户code的完整地址
StringBuilder weCharAuthCodeUrl = new StringBuilder(weChatAuthConfig.getCodeUri());
weCharAuthCodeUrl.append("?appid=").append(weChatAuthConfig.getAppId())
.append("&redirect_uri=").append(weChatAuthConfig.getRedirectUri())
.append("&response_type=code")
//&scope=snsapi_userinfo&state=STATE
.append("&scope=").append("snsapi_userinfo")
.append("&state=").append("kh96_wechat_auth")
.append("#wechat_redirect");
log.info("------ 请求微信官方授权网站地址:{} ------",weCharAuthCodeUrl.toString());
//返货完整的请求地址
return weCharAuthCodeUrl.toString();
}
/**
* @author : huayu
* @date : 29/10/2022
* @param : [wechatAuthCode]
* @return : java.lang.String
* @description : 根据微信回调的code值,请求微信官方获取用户access_token
*/
@Override
public String getAccessTokenFromWechatUseCode(String wechatAuthCode) {
// 尤其注意:由于公众号的 secret 和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。
// 请求方法:获取 code 后,请求以下链接获取access_token:
// https://api.weixin.qq.com/sns/oauth2/access_token
// ?appid=APPID
// &secret=SECRET
// &code=CODE
// &grant_type=authorization_code
// 封装根据code,请求微信官方获取access_token的完整地址
StringBuilder accessTokenUrl = new StringBuilder(weChatAuthConfig.getAccessTokenUri());
accessTokenUrl.append("?appid=").append(weChatAuthConfig.getAppId())
.append("&secret=").append(weChatAuthConfig.getAppSecret())
.append("&code=").append(wechatAuthCode)
.append("&grant_type=authorization_code");
log.info("------ 根据code,请求微信官方获取access_token的完整地址:{} ------", accessTokenUrl.toString());
// 根据code,请求微信官方获取access_token,返回结果是同步返回的,不再是异步回调
// 请求是服务器内部发起的,也就是说:在程序中,要根据上面完整的请求地址,主动发送请求到微信官方,接口同步会返回一个json格式的字符串结果,程序内要解析获取的结果
// 程序内主动发起http请求,获取access_token
return HttpClient4Util.getResponse4GetAsString(accessTokenUrl.toString(), "utf-8");
}
/**
* @author : huayu
* @date : 29/10/2022
* @param : [accessToken, openId]
* @return : java.lang.String
* @description : 根据用户的 accessToken 和 openId 拉取用户信息
*/
@Override
public String getUserInfoFromWechatUseAccessToken(String accessToken, String openId) {
// 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和 openid 拉取用户信息了。
// http:GET(请使用 https 协议):
// https://api.weixin.qq.com/sns/userinfo
// ?access_token=ACCESS_TOKEN
// &openid=OPENID
// &lang=zh_CN
// 封装根据accessToken和openId,请求微信官方获取用户信息详情地址
StringBuilder userInfoUrl = new StringBuilder(weChatAuthConfig.getUserInfoUri());
userInfoUrl.append("?access_token=").append(accessToken)
.append("&openid=").append(openId)
.append("&lang=zh_CN");
log.info("------ 根据access_token,请求微信官方获取userinfo的完整地址:{} ------", userInfoUrl.toString());
// 程序内主动发起http请求,获取用户详情
return HttpClient4Util.getResponse4GetAsString(userInfoUrl.toString(), "utf-8");
}
}
6、controller 层
/**
* Created On : 28/10/2022.
*
* Author : huayu
*
* Description: 测试微信授权登录操作入口
*/
//@SuppressWarnings("all")
@Slf4j
@RestController
@RequestMapping("/wechat/auth")
public class WeChatAuthController {
@Autowired
private WeChatAuthService weChatAuthService;
/**
* @author : huayu
* @date : 28/10/2022
* @param : []
* @return : com.kgc.scd.uitl.RequestResult
* @description : 获取请求微信官方货物code的完整地址,用户访问该地址,可以进行授权操作(把地址交给前端生成二维码给用户扫码,或者后端生成)
*/
@GetMapping("/codeUrl")
public RequestResult codeUrl(){
//调用业务接口,获取完整用户授权访问的地址
return ResultBuildUtil.success(weChatAuthService.generateWeChatAuthCodeUrl());
}
/**
* @author : huayu
* @date : 28/10/2022
* @param : []
* @return : com.kgc.scd.uitl.RequestResult>
* @description : 接收微信官方一步回调请求,获取用户授权的code
* 流程:用户先根据上一步返回请求地址,进行授权操作,如果用户统一授权,微信官方自动根据上一步请求带过去的回调地址redirectUri,进行结果回调
*/
@RequestMapping("/codeBack")
public RequestResult