前言
如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。
如果你想要获取到用户的信息,openId等,在这其中就需要微信的网页授权功能
在实现网页授权的时候,需要对于公众号先配置好网页授权域名
「设置与开发」-「功能设置」-「网页授权域名」
写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头
这个是关于域名的说明:
这样配置
问题前瞻
-
获取accessToken报错:
UnknownContentTypeException....[text/plain]
对象接收换成String接收,Json工具转化成对象,具体看这里
-
获取用户信息报错:
UnknownContentTypeException....[text/plain]
对象接收换成String接收,Json工具转化成对象,具体看这里
-
用户信息昵称乱码
接收对象之后,针对昵称进行转码。具体看这里
正文
1. 步骤
1.1 用户同意授权,获取code
1.2 通过code换取网页授权accessToken
1.3 获取网页授权access_token
2. 说明
2.1 网页授权accessToken的scope
2.2 网页授权与基础支持两个accessToken区别
3. 操作
3.1 用户同意授权,获取code
确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(已认证服务号,默认拥有scope参数中的snsapi_base和snsapi_userinfo 权限)
3.1.1 打开链接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
参考链接(请在微信客户端中打开此链接体验):
scope为snsapi_base:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect
scope为snsapi_userinfo:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx807d86fb6b3d4fd2&redirect_uri=http%3A%2F%2Fdevelopers.weixin.qq.com&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
尤其注意:跳转回调redirect_uri,应当使用https链接来确保授权code的安全性。
tips: 这一步是前端同学引导用户的,具体的参数含义可以参考微信开发者这里
用户同意授权后
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
code说明:
code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
这部分配置的跳转路径归属于前面配置的域名名下的路径。
这个就是显式授权的样子:
3.2 通过code换取网页授权accessToken
这个通过code获取的accessToken与基础支持的token(调用其他接口需要的)不一样,
它可以说是专门用来获取用户信息这个接口的区分于(网页授权的作用域为snsapi_base
与snsapi_userinfo
)
GET https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
3.2.1 调用接口报错
错误类型:UnknownContentTypeException....[text/plain]
因为微信的Content-Type是text/plain
。对象接报错了。
走到这里网页授权的作用域为snsapi_base就结束了。
网页授权的作用域为snsapi_userinfo还有最后一步
获取到accessToken之后就可以去求用户信息了
3.3 获取微信用户信息
GET https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
3.3.1 获取用户信息接口报错
错误类型:UnknownContentTypeException....[text/plain]
原因:restTemplate的Content-Type没有text/plain
。因为微信设置的这个响应头里面的Content-Type是text/plain
,而用对象去接收的话会报错。
解决方法:
- 用String去接,然后通过Json工具(用的是
fastjson2
)转化成对象。
import com.alibaba.fastjson2.JSONObject;
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate
.exchange(url,
HttpMethod.GET,
new HttpEntity<>(null),
String.class
);
String body = responseEntity.getBody();
AuthorizationUser user = JSONObject
.parseObject(body, AuthorizationUser.class);
- 自定义 HttpMessageConverter
这个方法实践过,主要因为只是涉及到微信的两个接口,没必要全局都设定。
有兴趣的读者可以参考解决 RestTemplate 报错 UnknownContentTypeException
这个是其他博主的。
3.3.2 昵称乱码
原因:调接口时未设置字符集,默认使用的字符集是 ISO-8859-1,该字符集不适合汉字和特殊字符
解决方法:
- 接收到的。 将字符集是 ISO_8859_1的昵称转换为 UTF-8
String transcoder = String.valueOf(code);
transcoder = new String(
transcoder.getBytes(EncodingConstant.ISO),
EncodingConstant.UTF_8
);
- 在发送请求的时候指定字符集
String requestUrl = String.format("", accessToken, openId);
try {
RestTemplate restTemplate = new RestTemplate();
// 创建一个StringHttpMessageConverter,并设置字符集为UTF-8
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
stringConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN));
// 将StringHttpMessageConverter添加到RestTemplate的消息转换器列表中
restTemplate.getMessageConverters().add(0, stringConverter);
// 创建HttpHeaders对象,设置Accept头部的值为"text/plain;charset=UTF-8"
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.TEXT_PLAIN));
headers.set(HttpHeaders.ACCEPT_CHARSET, "UTF-8");
String responseStr = restTemplate.getForObject(requestUrl, String.class);
JSONObject response = JSONObject.parseObject(responseStr);
} catch (Exception e) {
throw new RuntimeException(e);
}
总结
网页授权是通过h5页面用户授权同意然后携带code跳转到指定的页面,然后可以通过url的剪切获得code,然后回传后端去获取到网页授权accessToken,去调用微信api获得用户信息的方法。
其中code被使用之后就会失效,每次调用都要去获取一次。
throw new RuntimeException(e);
}
## 总结
网页授权是通过h5页面用户授权同意然后携带code跳转到指定的页面,然后可以通过url的剪切获得code,然后回传后端去获取到网页授权accessToken,去调用微信api获得用户信息的方法。
其中code被使用之后就会失效,每次调用都要去获取一次。
微信获取用户信息的接口通过第一步跳转的参数`scope`不同值可以只能获取到openId,还是可以获取到用户信息。