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

我们微信公众号使用的是我的测试号,地址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");

        // 用户同意授权后,能获取到code
        String code = request.getParameter("code");
        String state = request.getParameter("state");
        String url= "";

        // 用户同意授权
        if (!"authdeny".equals(code)) {
            // 获取网页授权access_token
            WeixinOauth2Token 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;
    }
}

 

这么一来就行了

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
基于微信小程序和SSM的课程设计是一种通过利用微信小程序和SSM框架来开发的课程设计项目。微信小程序是一种可以在微信平台上运行的轻量级应用,而SSM则是一种JavaEE开发框架,包括Spring、SpringMVC和MyBatis。 在这个课程设计中,我们可以利用微信小程序的特性来实现课程的展示、选课、评价等功能。用户可以通过微信小程序浏览课程列表,查看课程详情,然后选择感兴趣的课程进行选课。同时,用户也可以对已选课程进行评价,提供反馈和建议。 使用SSM框架可以实现后台的数据管理和处理。首先,通过MyBatis可以方便地进行数据库操作,存储和管理课程、用户等信息。然后,通过Spring可以实现业务逻辑的管理,包括课程的增删改查、用户身份验证功能。最后,通过SpringMVC可以实现与前端微信小程序的交互,处理前端请求并返回相应的数据。 通过结合微信小程序和SSM框架,我们可以实现一个简洁而功能丰富的课程管理系统。这个系统可以为学生提供方便快捷的选课体验,同时也可以帮助教师和管理员更好地管理和评估课程。而且,通过微信小程序的平台特性,用户可以随时随地通过手机进行课程管理,提高了用户的使用体验。总的来说,基于微信小程序和SSM的课程设计将提供一个全新的课程管理方案,使得选课和管理更加便捷和高效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值