前言
在一次前端项目中,需要在网页端拉起微信,实现微信授权登录,然后把调用微信API,获取到用户信息,返回给后端。
网页授权分为两种,一种静默授权,一种非静默授权。微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
这篇文章就讲诉一下如何实现微信授权登录。
网页授权的两种 scope 的区别
- 以
snsapi_base
为 scope 发起的网页授权,是用来获取进入页面的用户的 openid 的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面) - 以
snsapi_userinfo
为 scope 发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
开发指南
- 引导用户进入授权页面同意授权,获取code
- 通过 code 换取网页授权access_token(与基础支持中的access_token不同)
- 如果需要,开发者可以刷新网页授权access_token,避免过期(非必需步骤)
- 通过网页授权access_token和 openid 获取用户基本信息(支持 UnionID 机制)
第一步:用户同意授权,获取code
scope若为snsapi_base
:即选择静默授权,调用此微信服务端API接口
https://open.weixin.qq.com/connect/oauth2/authorize?appid=appId&redirect_uri=redirect_uri&response_type=code&scope=snsapi_base&state=123#wechat_redirect
scope若为snsapi_userinfo
:即选择非静默授权,调用此微信服务端API接口
https://open.weixin.qq.com/connect/oauth2/authorize?appid=appId&redirect_uri=redirect_uri&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
参数说明:
第二步:通过 code 换取网页授权access_token
如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。
请求方法:
获取 code 后,请求以下链接获取access_token:
第三步:拉取用户信息(需 scope 为 snsapi_userinfo)
如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和 openid 拉取用户信息了。
请求方法
http:GET(请使用 https 协议):https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
代码实现:
前端:
需要引入jquery插件
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
function getCode() {
$.ajax({
url: "/oauth",
type: "get",
success(res) {
window.location.href = res.data;
}
})
}
function isCode() {
return window.location.search.includes('code=')
}
function lanuch() {
if (isCode()) {
console.log("getCode");
} else {
this.getCode()
}
}
lanuch();
后端接口:
**
* 微信网页授权
*/
@RestController
@Slf4j
public class WeixinOauthHandler {
/**
* 第一步:用户同意授权,获取code
*
* @param response
*/
@RequestMapping("/oauth")
public void oauth(HttpServletResponse response) throws IOException {
// 项目服务器url
String path = "http://***:9936/" + "invoke";
try {
path = URLEncoder.encode(path, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=你的公众号appid" +
"&redirect_uri=" + path +
"&response_type=code" +
"&scope=snsapi_userinfo" +
"&state=comi" +
"#wechat_redirect";
log.info("url===" + url);
response.sendRedirect(url);
}
/**
* 第二步:用户同意授权,页面跳转至/invoke
*
* @param request
*/
@RequestMapping("/invoke")
public void invoke(HttpServletRequest request) {
String code = request.getParameter("code");
log.info("code=====" + code);
//通过code获取ACCESS_TOKEN
//认证服务器
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=您的公众号appid" +
"&secret=您的公众号密钥" +
"&code=" + code +
"&grant_type=authorization_code";
String object = HttpUtil.doGet(url);
JSONObject jsonObject = JSONObject.parseObject(object);
log.info("jsonObject====" + jsonObject);
String access_token = jsonObject.getString("access_token");
String openid = jsonObject.getString("openid");
//第三步:拉取用户信息
String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?" +
"access_token=" + access_token +
"&openid=" + openid +
"&lang=zh_CN";
String userInfo = HttpUtil.doGet(userInfoUrl);
JSONObject userJson = JSONObject.parseObject(userInfo);
log.info("userJson=====" + userJson);
}
}
效果图
可以获取到国家、地区、openid、code、微信昵称、微信头像、性别、语言等等字段。
总结
顺便给大家提供一个微信公众号测试平台:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
需要在微信公众号后台配置后,才能后台才能调用成功哦~