我们微信公众号使用的是我的测试号,地址https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

1.微信测试号后台配置

注意,这个配置要成功,否则是会显示配置失败的。后台怎么写,看下面

2.后台代码

2.1验证token的代码

控制器里:

@RequestMapping(value = "/wxcheck")
public void check(Model model, HttpServletRequest request, HttpServletResponse response)throws IOException {boolean isGet = request.getMethod().toLowerCase().equals("get");PrintWriter print;if(isGet){// 微信加密签名String signature = request.getParameter("signature");// 时间戳String timestamp = request.getParameter("timestamp");// 随机数String nonce = request.getParameter("nonce");// 随机字符串String echostr = request.getParameter("echostr");// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败if (signature != null && WechatUtil.checkSignature(signature, timestamp, nonce)) {try {print = response.getWriter();print.write(echostr);print.flush();} catch (IOException e) {e.printStackTrace();}}}
}

WechatUtil这个工具类:

public class WechatUtil {/*** 与接口配置信息中的Token要一致*/private static String token = "xxx";/*** 验证签名** @param signature* @param timestamp* @param nonce* @return*/public static boolean checkSignature(String signature, String timestamp, String nonce) {String[] arr = new String[] { token, timestamp, nonce };// 将token、timestamp、nonce三个参数进行字典序排序// Arrays.sort(arr);sort(arr);StringBuilder content = new StringBuilder();for (int i = 0; i < arr.length; i++) {content.append(arr[i]);}MessageDigest md = null;String tmpStr = null;try {md = MessageDigest.getInstance("SHA-1");// 将三个参数字符串拼接成一个字符串进行sha1加密byte[] digest = md.digest(content.toString().getBytes());tmpStr = byteToStr(digest);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}content = null;// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;}/*** 将字节数组转换为十六进制字符串** @param byteArray* @return*/private static String byteToStr(byte[] byteArray) {String strDigest = "";for (int i = 0; i < byteArray.length; i++) {strDigest += byteToHexStr(byteArray[i]);}return strDigest;}/*** 将字节转换为十六进制字符串** @param mByte* @return*/private static String byteToHexStr(byte mByte) {char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };char[] tempArr = new char[2];tempArr[0] = Digit[(mByte >>> 4) & 0X0F];tempArr[1] = Digit[mByte & 0X0F];String s = new String(tempArr);return s;}public static void sort(String a[]) {for (int i = 0; i < a.length - 1; i++) {for (int j = i + 1; j < a.length; j++) {if (a[j].compareTo(a[i]) < 0) {String temp = a[i];a[i] = a[j];a[j] = temp;}}}}
}

这么一来,微信通过token验证我们的服务器就能通过了。

2.获取微信授权信息

首先按钮的格式:这个是比较麻烦的地方,格式必须一模一样

{"button": [{"type": "click","name": "xxx","key": "1"},{"name": "常见问题","sub_button": [{"type": "view","name": "xxx","url": "http://www.xxx"},{"type": "view","name": "xxx","url": "http://www.xxx"},{"type": "view","name": "xxx","url":  "http://www.xxx"}]},{"name":"个人中心","sub_button":[{"type": "view","name": "测试","url" : "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxXXXXX95&redirect_uri=http%3A%2F%2FXXXXXXXXXXcom%2Flxxxxxxe%2Fauth&response_type=code&scope=snsapi_base&state=123#wechat_redirect"},{"type": "click","name": "我要提问","key" : "103"}]}]}

我使用的是基本方法不获取userinfor,是默认同意授权的,控制器里的写法

 @RequestMapping(value = "/auth")public void wxAuth(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");// 用户同意授权后,能获取到codeString code = request.getParameter("code");String state = request.getParameter("state");String url= "";// 用户同意授权if (!"authdeny".equals(code)) {// 获取网页授权access_tokenWeixinOauth2Token weixinOauth2Token = WechatUtil.getOauth2AccessToken("id", "密码", code);// 网页授权接口访问凭证String accessToken = weixinOauth2Token.getAccessToken();// 用户标识String openId = weixinOauth2Token.getOpenId();String ip = IpUtil.getIpAddr(request);WxOpenid wxOpenid = new WxOpenid();wxOpenid.setIp(ip);wxOpenid.setCreatTime(new Date());wxOpenid.setOpenid(openId);int i = wxOpenidService.insertSelective(wxOpenid);System.out.println(">>>>>>>>>>>>>>>>>>>>"+ip);
//            // 获取用户信息
//            SNSUserInfo snsUserInfo = AdvancedUtil.getSNSUserInfo(accessToken, openId);// 设置要传递的参数
//            request.setAttribute("snsUserInfo", snsUserInfo);
//            request.setAttribute("state", state);}url = "http://xxx/xxx/";// 跳转到xxx前台response.sendRedirect(url);}

用到的工具类:

 /*** 获取网页授权凭证** @param appId 公众账号的唯一标识* @param appSecret 公众账号的密钥* @param code* @return WeixinAouth2Token*/public static WeixinOauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {WeixinOauth2Token wat = new WeixinOauth2Token();// 拼接请求地址String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";requestUrl = requestUrl.replace("APPID", appId);requestUrl = requestUrl.replace("SECRET", appSecret);requestUrl = requestUrl.replace("CODE", code);// 获取网页授权凭证JSONObject jsonObject = HttpCommonUtil.httpsRequest(requestUrl, "GET", null);if (null != jsonObject) {try {wat.setAccessToken(jsonObject.getString("access_token"));wat.setExpiresIn(jsonObject.getInteger("expires_in"));wat.setRefreshToken(jsonObject.getString("refresh_token"));wat.setOpenId(jsonObject.getString("openid"));wat.setScope(jsonObject.getString("scope"));} catch (Exception e) {
//                wat = null;
//                int errorCode = jsonObject.getInteger("errcode");
//                String errorMsg = jsonObject.getString("errmsg");
//                log.error("获取网页授权凭证失败 errcode:{} errmsg:{}", errorCode, errorMsg);}}return wat;}

还有一个网页授权信息的实体类:

/*** 类名: WeixinOauth2Token </br>* 描述:  网页授权信息  </br>* 开发人员: fr</br>* 发布版本:V1.0  </br>*/
public class WeixinOauth2Token {// 网页授权接口调用凭证private String accessToken;// 凭证有效时长private int expiresIn;// 用于刷新凭证private String refreshToken;// 用户标识private String openId;// 用户授权作用域private String scope;public String getAccessToken() {return accessToken;}public void setAccessToken(String accessToken) {this.accessToken = accessToken;}public int getExpiresIn() {return expiresIn;}public void setExpiresIn(int expiresIn) {this.expiresIn = expiresIn;}public String getRefreshToken() {return refreshToken;}public void setRefreshToken(String refreshToken) {this.refreshToken = refreshToken;}public String getOpenId() {return openId;}public void setOpenId(String openId) {this.openId = openId;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}

还有一个发送http请求的工具类

package com.wolwo.base.util;import com.alibaba.fastjson.JSONObject;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.security.SecureRandom;
import javax.net.ssl.*;public class HttpCommonUtil {/*** 发送https请求** @param requestUrl 请求地址* @param requestMethod 请求方式(GET、POST)* @param outputStr 提交的数据* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)*/public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {JSONObject jsonObject = null;try {// 创建SSLContext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = { new MyX509TrustManager() };SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new SecureRandom());// 从上述SSLContext对象中得到SSLSocketFactory对象SSLSocketFactory ssf = sslContext.getSocketFactory();URL url = new URL(requestUrl);HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();conn.setSSLSocketFactory(ssf);conn.setDoOutput(true);conn.setDoInput(true);conn.setUseCaches(false);// 设置请求方式(GET/POST)conn.setRequestMethod(requestMethod);// 当outputStr不为null时向输出流写数据if (null != outputStr) {OutputStream outputStream = conn.getOutputStream();// 注意编码格式outputStream.write(outputStr.getBytes("UTF-8"));outputStream.close();}// 从输入流读取返回内容InputStream inputStream = conn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;StringBuffer buffer = new StringBuffer();while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}// 释放资源bufferedReader.close();inputStreamReader.close();inputStream.close();inputStream = null;conn.disconnect();jsonObject  = JSONObject.parseObject(buffer.toString());} catch (ConnectException ce) {
//            log.error("连接超时:{}", ce);} catch (Exception e) {
//            log.error("https请求异常:{}", e);}return jsonObject;}
}
package com.wolwo.base.util;import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;/*** 类名: MyX509TrustManager </br>* 描述:信任管理器 </br>* 开发人员: fr</br>* 发布版本:V1.0  </br>*/
public class MyX509TrustManager implements X509TrustManager {// 检查客户端证书public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}// 检查服务器端证书public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}// 返回受信任的X509证书数组public X509Certificate[] getAcceptedIssuers() {return null;}
}

IpUtil.java

package com.wolwo.base.util;import javax.servlet.http.HttpServletRequest;public class IpUtil {/*** 获取登录用户IP地址** @param request* @return*/public static String getIpAddr(HttpServletRequest request) {String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}if (ip.equals("0:0:0:0:0:0:0:1")) {ip = "本地";}return ip;}
}
WxOpenid.java
package com.wolwo.wx.domain;import java.sql.Timestamp;
import java.util.Date;public class WxOpenid {private String ip;private String openid;private Date createTime;public String getIp() {return ip;}public void setIp(String ip) {this.ip = ip;}public String getOpenid() {return openid;}public void setOpenid(String openid) {this.openid = openid;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}
}

这么一来就行了

用ssm进行微信开发,实现微信登录验证功能相关推荐

  1. 微信鉴权服务器地址,微信开发之微信授权登录

    本篇教程探讨了微信开发之微信授权登录,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入. < 应用场景是:用Hbuilder打包app,在app中点击微信授权登录或者某一操作, ...

  2. 微信开发:微信js_sdk 分享,前端部分(二)

    微信开发:微信js-sdk前端分享,代码如下: <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"> ...

  3. php 微信 语音,PHP语言微信开发:微信录音临时转永久存储

    本文主要向大家介绍了PHP语言微信开发:微信录音临时转永久存储,通过具体的内容向大家展示,希望对大家学习php语言有所帮助. 最近做开发的时候碰到了这个问题,甲方希望用户在微信端的录音能够一直有效.就 ...

  4. 微信开发 --- 调用微信上传图片接口,并保存到自己的服务器

    微信开发 - 调用微信上传图片接口,并保存到自己的服务器 整体思路是这样的: 1.先把手机上的图片上传到微信服务器,然后返回一个图片ID 2.在通过后台根据ID从微信后台拿到流,保存到服务器 前几个步 ...

  5. html登录验证功能,续:实现用户登录验证功能

    一.提纲 1.Previously前情提要 已经把Thymeleaf部署到项目中: 把前端开发的静态资源成功引入到项目中: 完成登录验证功能,登录成功跳转到success.html页面,登录失败跳转到 ...

  6. shiro 实现登录验证功能

    实现登录验证功能 1.创建自己的Realm对象,继承AuthorizingRealm ​    实现父类的doGetAuthenticationInfo 认证方法 MyRealm.java packa ...

  7. JSP脚本实现登录验证功能

    JSP脚本实现登录验证功能 登录 点击退出 登录页面login <%@ page contentType="text/html;charset=UTF-8" language ...

  8. php post验证输入,$.post()登录验证功能

    $.post()登录验证功能 用户登录 邮箱 密码 登录 /** * $_post():jquery处理ajax中的post请求 * 基本语法:$.post(url, data, success, d ...

  9. php静态登录界面代码,JSP_JSP登录验证功能的实现,静态的登录界面的设计login.htm - phpStudy...

    JSP登录验证功能的实现 静态的登录界面的设计login.htm,代码如下: 系统登录 系 统 登 录 用户名            密  码        将登录用户输入的信息提交到login.js ...

  10. 【博客项目】—登录验证功能实现( 五)

    [博客项目]-登录验证功能实现( 五)

最新文章

  1. Learn OpenGL (十一):光照贴图
  2. Utilize Sql Tuning Advisor from Script
  3. 劝你别把开源的AI项目写在简历上了!!!
  4. PO,VO,DAO,BO,POJO 之间的区别你懂吗?
  5. Linux课程第二十一天学习笔记
  6. 学习python之序言
  7. docker mysql:8.0.27
  8. Zookeeper-Watcher(事件通知)
  9. JavaScript的初步探索(JS的入坑笔录)
  10. Tomcat access log配置
  11. syn flag flooding防御
  12. 7个和尚_一位高僧对世俗问题的7个回答,非常绝妙!
  13. chrome升级后无高级-断续访问
  14. js版算24点小游戏
  15. 十套精美个人博客网站模板
  16. 2022年最新京东滑块验证码破解思路(算法过验)
  17. Redis远程连接出现An existing connection was forcibly closed by the remote host.远程主机强制关闭现有连接
  18. 海洋cms php环境 多少,海洋cms
  19. 关于回溯法的递归与非递归-----N皇后问题
  20. 基于数字孪生的智慧城市

热门文章

  1. CTF之Bugku 秋名山老司机
  2. 2021-11-12 Capturing Car-Following Behaviors by Deep Learning
  3. 数据分析报告这样写,才算真正读懂了数据
  4. 各类开发生产环境缩写
  5. 1072 开学寄语 (20分)
  6. 高斯过程动态模型(GPDM)简析
  7. 一些牛逼哄哄的javascript面试题
  8. Linux 解决无法清空回收站问题
  9. R语言需要C语言基础吗,R语言入门(1)-初识R语言
  10. JAVA项目接入腾讯应用宝YSDK平台之QQ微信登录接入模式详解