文章目录
首先,我们前往微信开放平台创建相应的开发者账号
由于我们使用的是网页应用
发送模板消息,是根据用户的openid发送模板消息的,公众号不同。用户的openid也不同。只针对同一个公众号下关注的微信用户,我们需要在网页应用绑定微信用户的openid
绑定微信用户流程
1、用户登录我们的网页应用。
2、提供绑定微信的跳转链接(可以通过微信扫二维码的方式)
3、授权获取用户的openid
4、将我们网页应用的用户绑定openid存入数据库
5、根据网页用户得知openid,拿到openid,发送模板消息
网页授权
两种授权模式
分别是
静默授权
:获取的信息不多,用户无感知授权
基本授权
:可以获取用户的基本信息,需要用户手动单击授权
我们的目的是获取当前公众号下用户的openid,所有两种授权模式都可以。
unionid:微信用户唯一id(唯一性,保持不变,用于微信授权登录) 待更新…
授权方式
需要指引用户打开对应的链接
参考链接(请在微信客户端中打开此链接体验):
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=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
参数说明
appid:你注册应用的唯一标识id
redirect_uri:授权回调域名,请与注册应用填写的保持一致,
response_type:code
scope:授权方式 snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )
state:会返回到回调域名并携带state参数
#wechat_redirect
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
页面跳转到我们填写的回调域名,前端只要接受,将state和code参数方式调用后端接口
这时候返回的code,就是我们需要的凭证信息,只能用一次,并且有时间限制。根据授权方式不同,我们根据code拿到的用户信息也不同,静默授权只能拿到用户的openid
用到的生成二维码工具类
前往我的另一篇原创文章获取,谢谢!
传送门
生成绑定微信的二维码链接
生成的二维码内容包含,需要绑定的网页用户id存入state,会通过回调传入后台。
/**
* 生成二维码,已base64形式返回前端
* @param request
* @param response
* @param param
* @throws IOException
* @throws WriterException
*/
@RequestMapping(method = RequestMethod.POST,value = "/generateQRcode")
public void generateQRcode(HttpServletRequest request,HttpServletResponse response,@RequestBody Map param) throws IOException, WriterException {
Map<String, String> state = new HashMap<>();
String userId = param.get("UserId").toString();
String data="https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的appid&redirect_uri=回调地址&response_type=code&scope=snsapi_userinfo&state="+userId+"#wechat_redirect";
//logo图标
File logoFile = new File("C:/Users/Administrator/Desktop/mosukj.jpg");
BufferedImage image = zxingUtil.createQRCodeWithLogo(data, logoFile);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(image, "png", stream);
String res = Base64Utils.encodeToString(stream.toByteArray());
renderResult(response, res);
}
注!!!!!!
renderResult是返回前端的封装,底层使用response里面的write方法,如需要,请前往我的另一篇文章
如图所示。单击请求接口,返回base64编码格式的图片
用户扫码后会跳转到redirect_uri/?code=CODE&state=二维码 中的state(网页用户id)
扫码后。用户手机会访问到回调地址。回调地址我们可以根据参数中是否包含code或state来显示手机上显示需要提示用户是否绑定的页面
如果所示:
前端收到后,再次请求后台。通过code换取openid或用户基本信息。
确定绑定后再次请求后端的绑定微信接口逻辑,如下。
用到的工具类方法
/**
* 获取网页授权用到的AccessToken
* @param code
* @return
*/
public static Map<String,String> getUserinfoAccessToken(String code){
String s = HttpUtil.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code");
Map<String,String> map = (Map) JSON.parse(s);
System.out.println(map);
return map;
}
/**
* 获取用户信息
* @param accessToken
* @param openid
* @return
*/
public static Map<String,String> getUserInfo(String accessToken,String openid){
String s = HttpUtil.sendGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN");
Map<String,String> map = (Map) JSON.parse(s);
System.out.println(map);
return map;
}
绑定逻辑代码如下
@RequestMapping(value = "/getUserinfo",method = RequestMethod.POST)
public void WebAuthor(String code,String state,HttpServletRequest request, HttpServletResponse response){
if(code!=null) {
Long UserId = Long.valueOf(state);
//1.通过code来换取access_token
Map<String, String> json = WeiXinUtil.getUserinfoAccessToken(code);
//获取网页授权access_token凭据
String webAccessToken = json.get("access_token");
//获取用户openid
String openid = json.get("openid");
//以下信息需要基本授权(需要用户手动授权才能获取到)
Map<String, String> userInfo = WeiXinUtil.getUserInfo(webAccessToken, openid);
String unoinId = userInfo.get("unionid");
System.out.println(userInfo);
QueryWrapper<SysUserOpenid> wrapper=new QueryWrapper<>();
wrapper.eq("union_id", unoinId);
wrapper.eq("user_id", UserId);
wrapper.ne("state", 9);
Integer integer = sysUserOpenidService.getBaseMapper().selectCount(wrapper);
QueryWrapper<SysUserOpenid> wrapper2=new QueryWrapper<>();
wrapper2.eq("union_id", unoinId);
wrapper.ne("state", 9);
Integer integer2 = sysUserOpenidService.getBaseMapper().selectCount(wrapper);
if (integer>0 && integer2>0){
renderResult(response, "当前账号已绑定");
}else {
//保存入库操作,根据需要修改
SysUserOpenid sysUserOpenid = new SysUserOpenid();
sysUserOpenid.setOpenId(openid);
sysUserOpenid.setUserId(UserId);
sysUserOpenid.setState(1);
sysUserOpenid.setCreateTime(LocalDateTime.now());
sysUserOpenid.setNickname(userInfo.get("nickname"));
sysUserOpenid.setImgurl(userInfo.get("headimgurl"));
sysUserOpenid.setUnionId(userInfo.get("unionid"));
boolean save = sysUserOpenidService.save(sysUserOpenid);
if (save){
renderResult(response, "绑定成功");
}else {
renderResult(response, "绑定失败");
}
}
}
renderResult(response, "code不能为空");
}
模板消息发送
完成以上操作,网页用户便与微信建立关系并绑定。当我们需要发送模板消息便可以根据用户找到openid并发送。微信模板发送消息,请前往
如有问题,欢迎大家评论讨论❤️❤️❤️