/** * 堆代码 duidaima.com * 二维码页面 * @return */ @RequestMapping("wx/connect/qrconnect") public String qrCode(){ return "qrconnect"; } qrconnect.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>微信扫码登录</title> <script src="/js/jquery.min.js" ></script> <script src="/js/jquery.qrcode.min.js" ></script> </head> <body> <h1>请扫码登录</h1> <a href="/wx/confirm"> <div id="qrcode"></div> </a> <script> $(function(){ $('#qrcode').qrcode({render:'canvas',text:"http://localhost:8080",width:160,height:160}); }); </script> </body> </html>因为我们没有在线的网址,所以就给二维码加了一个点击事件,模拟扫码跳转。
/** * 用户授权页面 * @return */ @RequestMapping("/wx/confirm") public String confirm(){ return "confirm"; }模拟扫码登录的授权页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>授权页面</title> </head> <body> <a href="/wx/pass?appid=wx123456&redirect_uri=wx&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect">同意</a> </body> </html>点同意后跳转到 /wx/pass ,正常的逻辑是跳转到微信的服务端,微信端会根据你传过来的 appid (因为你已经认证过了,所以会直接跳转到你的回调地址,并且带上临时票据 code )。临时票据的作用是你用来获取微信用户的 openid 和 access_token ,这个操作需要你在回调接口中处理。
/** * 用户确认授权 * @return */ @GetMapping("/wx/pass") public String pass(String appid, String redirect_uri, Model model){ String appSecret = "87wjef4453deg432"; String code = "abc"; //模拟临时票据 //通过 app_id, app_secret 和 code 获取接口调用凭证 access_token 和 授权用户唯一标识 openid String getAccessTokenURLFormat = "http://localhost:8080/wx/sns/oauth2/access_token?appid={}&secret={}&code={}&grant_type=authorization_code"; String getAccessTokenURL = StrUtil.format(getAccessTokenURLFormat, appid,appSecret,code); //通过 hutool 工具类 访问url String tokenResponse = HttpUtil.get(getAccessTokenURL); //通过 hutool 工具类 转换为 json 对象 JSONObject tokenJson= JSONUtil.parseObj(tokenResponse); //获取json 对象相关字段 Integer errcode = (Integer)tokenJson.get("errcode"); String errmsg = (String)tokenJson.get("errmsg"); String openid = (String)tokenJson.get("openid"); //微信用户的唯一标识,可以跟自己数据库的用户进行关联 String access_token = (String)tokenJson.get("access_token"); //作用是获取该微信用户的具体信息 model.addAttribute("openid",openid); model.addAttribute("access_token",access_token); return redirect_uri; }http://localhost:8080/wx/sns/oauth2/access_token?appid={}&secret={}&code={}&grant_type=authorization_code
/** * 模拟获取AccessToken * @return */ @GetMapping("/wx/sns/oauth2/access_token") @ResponseBody public String getAccessToken(String appid,String secret,String code){ JSONObject json = new JSONObject(); json.set("errcode",null); json.set("errmsg",null); json.set("openid","666"); json.set("access_token","&HG^FUI"); return json.toString(); }用到了hutool的方法,hutool依赖别忘了导入:
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.20</version> </dependency>最终返回的页面是wx.html
<!DOCTYPE html> <html> <head> <title>堆代码 duidaima.com</title> </head> <body> <span th:text="'恭喜,微信登录成功。openid:' + ${openid} + ', access_token:' + ${access_token}"></span> </body> </html>
这样一来,当我点同意,就进入回调,回调再模拟远程调用获取openId,得到: