在web端用到weChat扫码登录,在手机扫码登陆成功后,跳转到相应的界面。
1、第一步请求code
调用接口:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect;
参数信息说明:
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用唯一标识 |
redirect_uri | 是 | 请使用urlEncode对链接进行处理 |
response_type | 是 | 填code |
scope | 是 | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即 |
state | 否 | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 |
前端代码信息如下(通过后台controller层返回url,来显示二维码):
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>微信扫码登录</title> <script type="text/javascript" src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script> <script type="text/javascript"> $().ready(function() { $.ajax({ url: "${base}/weChat", type: "post", dataType: "json", success: function(data) { var div = document.getElementById("login_container"); div.innerHTML = ""; var iframe = document.createElement("iframe"); var url = data.url; var redirect_uri = data.redirect_uri; var code = url+encodeURIComponent(redirect_uri); iframe.setAttribute("src",code); iframe.style.width = "100%"; iframe.style.height = "100%"; div.appendChild(iframe); } }); }); </script></head><body> <!--内容--> <div class="content"> <div id="login_container" class="login_container"></div> </div></body></html>
后台代码(controller层获取code的url信息)
/** * 微信扫码登录二维码显示 */ @PostMapping("/weChat") public ResponseEntity weChat(HttpServletRequest request) { Map<String, Object> map = new HashMap<>(5); String state = DigestUtils.md5Hex(UUID.randomUUID() + RandomStringUtils.randomAlphabetic(30)); request.getSession().setAttribute(STATE_ATTRIBUTE_NAME, state); String redirect_uri = "http://hbbdjw.nat300.top/social_user_login/get_sign_in_weixinQrCodeLoginPlugin";//红色部分改为自己的redirect_url,蓝色部分改为自己的扫码后需要跳转的页面 String url = "https://open.weixin.qq.com/connect/qrconnect?appid=【自己的appid】&scope=snsapi_login&response_type=code&state=" + state + "&redirect_uri="; map.put("url", url); map.put("redirect_uri", redirect_uri); return ResponseEntity.ok(map); }
2、第二步:通过code获取access_token
登陆后处理(判断access_token是否为null,不为空,则验证成功,否则失败)
/** * 登录后处理 */ @GetMapping({"/get_sign_in_weixinQrCodeLoginPlugin"}) public ModelAndView getSignin(@PathVariable String loginPluginId, @PathVariable(required = false) String extra, HttpServletRequest request, HttpServletResponse response, ModelMap model, RedirectAttributes redirectAttributes) throws Exception { String getTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=【自己的appid】&secret=【自己的secret】&code=" + code + "&grant_type=authorization_code"; // 获取网页授权凭证 JSONObject jsonObject = JSONObject.fromObject(HttpUtil.Get(getTokenUrl));//get方法是自己写的 if (jsonObject != null) { String openId = jsonObject.getString("access_token"); String accessToken = jsonObject.getString("openid"); String uniqueId = jsonObject.getString("openid"); } SocialUser socialUser = socialUserService.find(uniqueId); //从数据库中查找用户,if (socialUser != null) { //当数据库中不存在该user的时候,事件处理 } else { //当数据库中存在该user的时候,事件处理(一般情况下新建user信息数据在数据库) }return modelAndView; }
GET请求方法
/** * 向指定URL发送GET方法的请求 * * @param url 发送请求的URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */ public static String Get(String url) { int connectionTimeOut=HTTP_CONNECTION_TIMEOUT, readTimeOut =HTTP_READ_TIMEOUT; String result = ""; BufferedReader in = null; String urlNameString = url; try { logger.info("请求url+参数:" + urlNameString); URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setConnectTimeout(connectionTimeOut); connection.setReadTimeout(readTimeOut); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { logger.error("发送GET请求出现异常!url: " + urlNameString + ", " + e); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { logger.error("close exception", e2); } } return result; }
到此结束。
原文地址:https://www.cnblogs.com/g-smile/p/9096493.html
时间: 2024-11-02 02:47:00