SpringBoot微信小程序授权登录

2023-11-16

SpringBoot微信小程序授权登录

一、appId

1.1、自己是管理者:微信公众平台,申请或登录自己的微信小程序,在开发者管理中即可看到
2.2、自己是开发者:让管理员将自己加入到小程序开发者管理中,用管理者提供的appId和secret,否则没有开发权限
在这里插入图片描述

二、小程序登录页面

2.1、打开HBuilderX开发工具,新建一个uni-app项目
在这里插入图片描述
2.2、在项目根目录下新建config文件夹,创建config.js文件,配置后台访问路径

// 配置后台服务器访问地址:ip:端口/项目名
const hostUrl = ''
export default {
  // 本地持久化存储key
  projectKey: 'XinJiangBS',
  // api请求地址
  // #ifdef H5
  // H5 环境,配合menifest.json中的devServe配置来解决调试时的跨域问题
  baseUrl: process.env.NODE_ENV === 'development' ? '/dev' : hostUrl,
  // #endif
  baseUrl: hostUrl,
  // 盐
  kSalt: 'XDSAKDSALMSD',
}

2.3、新建简单的login.vue页面,调用前端方法获取后台登录需要用的code信息

<button @click="toLogin">获取登录code</button>
// 可以将后台接口统一写在common.js中,页面统一引入
import { } from "@/api/common.js"
methods:{
	toLogin(){
		uni.getProvider({
			service:'oauth',
			success:(provider) => {
			uni.login({
				success:(loginCode) =>{
					console.log("loginCode",loginCode);
					// todo 调用后台登录接口,参数code
				}
			})
		}
	})
	},
}

2.4、下载微信开发者工具,并安装
在这里插入图片描述
2.5、配置HBuilderX,点击manifest.json,再点击微信小程序配置appid
在这里插入图片描述
2.6、配置运行小程序需要用到的微信开发开发者工具,点击HBuilder上面工具栏中的:工具—设置—运行配置,找到微信开发者工具工具路径,配置2.4中安装安装时的路径

三、java代码部分

1.新建微信小程序公用配置文件
@Component
@Slf4j
public class WxDataConfigure {

    /**小程序appId*/
    public static String appId = "";

    /**小程序的秘钥*/
    public static String ** = "";

    /**商户号*/
    public static String mch_id = "";

    /**商户支付秘钥V2*/
    public static String key = "";
    /**商户支付秘钥V3*/
    public static String keyV3 = "";

    /**退款用到*/
    public static String certUrl = "";

    /**商家转账到零钱*/
    public static String pemUrl = "";
    public static String privateKeyPath = "";
    public static String privateCertPath = "";
    public static String sn = "";

    /**商户证书序列号*/
    public static String serial_no = "";

    /**回调通知地址(需内网穿透测试)*/
    public static String notify_url = "";

    /**交易类型*/
    public static  String trade_type = "JSAPI";

    /**统一下单API接口链接*/
    public static String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    /**查询订单API接口链接*/
    public static String query_url = "https://api.mch.weixin.qq.com/pay/orderquery";

    /**退款接口*/
    public static String refund_url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";

    /**退款回调接口*/
    public static String refund_notify_url = "";

    /**商家转账到零钱*/
    public static String batches_url = "https://api.mch.weixin.qq.com/v3/transfer/batches";

    /**
     * 预支付
     * @return
     */
    public static WxPayService unifiedOrderWxPayService() {
        log.info("======================初始化微信支付接口服务开始======================");
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(appId);
        payConfig.setMchId(mch_id);
        payConfig.setMchKey(key);
        payConfig.setKeyPath(certUrl);
        payConfig.setTradeType(trade_type);

        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);

        log.info("======================初始化微信支付接口服务完成======================");
        return wxPayService;
    }

    /**
     * 退款
     * @return
     */
    public static WxPayService wxPayService() {
        //logger.info("======================初始化微信支付接口服务开始======================");
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(appId);
        payConfig.setMchId(mch_id);
        payConfig.setPrivateKeyPath(privateKeyPath);
        payConfig.setNotifyUrl(refund_notify_url);
        payConfig.setApiV3Key(keyV3);
        payConfig.setPrivateCertPath(privateCertPath);
        payConfig.setCertSerialNo(serial_no);

        payConfig.setMchKey(key);
        payConfig.setKeyPath(certUrl);
        payConfig.setTradeType(trade_type);

        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);

        //logger.info("======================初始化微信支付接口服务完成======================");
        return wxPayService;
    }

2.调用微信服务器接口的请求方法类

public class HttpRequest {
    //连接超时时间,默认10秒
    private static final int socketTimeout = 10000;

    //传输超时时间,默认30秒
    private static final int connectTimeout = 30000;


    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url   发送请求的URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }


    /**
     * post请求
     *
     * @throws IOException
     * @throws ClientProtocolException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws KeyManagementException
     * @throws UnrecoverableKeyException
     */
    public static String sendPost(String url, Object xmlObj) throws ClientProtocolException, IOException, UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException {


        HttpPost httpPost = new HttpPost(url);
        //解决XStream对出现双下划线的bug
        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
        xStreamForRequestPostData.alias("xml", xmlObj.getClass());
        //将要提交给API的数据对象转换成XML格式数据Post给API
        String postDataXML = xStreamForRequestPostData.toXML(xmlObj);
        System.out.println(postDataXML);
        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);

        //设置请求器的配置
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
        httpPost.setConfig(requestConfig);

        HttpClient httpClient = HttpClients.createDefault();
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "UTF-8");
        return result;
    }

    /**
     * http POST 请求
     *
     * @param url:请求地址
     * @param body:     body实体字符串
     * @param certPath: 证书路径
     * @param password: 证书密码
     * @return
     */
    public static String httpPostReflect(String url, String body, InputStream certPath, String password) {
        String xmlRes = "{}";
        HttpClient client = createSSLClientCert(certPath, password);
        HttpPost httpost = new HttpPost(url);
        try {
            //所有请求的body都需采用UTF-8编码
//            StringEntity entity = new StringEntity(body,"UTF-8");
//            httpost.setEntity(entity);
            //支付平台所有的API仅支持JSON格式的请求调用,HTTP请求头Content-Type设为application/json
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/json; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            //httpost.addHeader("Authorization",Configure.sn + " " + data);
            httpost.setEntity(new StringEntity(body, "UTF-8"));
            HttpResponse response = client.execute(httpost);
            //所有响应也采用UTF-8编码
            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            xmlRes = result;
        } catch (ClientProtocolException e) {
            System.out.println(e);
        } catch (UnknownHostException e) {
            System.out.println(e);
        } catch (IOException e) {
            System.out.println(e);
        }
        return xmlRes;
    }

    /**
     * 创建带证书的实例
     *
     * @param certPath
     * @return
     */
    public static CloseableHttpClient createSSLClientCert(InputStream certPath, String password) {
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(certPath, password.toCharArray());
            certPath.close();
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //信任所有
                public boolean isTrusted(X509Certificate[] chain,
                                         String authType) throws CertificateException {
                    return true;
                }
            }).loadKeyMaterial(keyStore, password.toCharArray()).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1", "TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            System.out.println(e);
        } catch (NoSuchAlgorithmException e) {
            System.out.println(e);
        } catch (KeyStoreException e) {
            System.out.println(e);
        } catch (FileNotFoundException e) {
            System.out.println(e);
        } catch (Exception e) {
            System.out.println(e);
        }
        return HttpClients.createDefault();
    }

    /**
     * 自定义证书管理器,信任所有证书
     *
     * @author pc
     */
    public static class MyX509TrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] arg0, String arg1)
                throws CertificateException {

        }

        @Override
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] arg0, String arg1)
                throws CertificateException {

        }

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}

3.微信登录方法,返回用户信息至前端

@Slf4j
@RestController
@RequestMapping("/wx/user")
public class WxController {

    /**
     *  //GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
     *  //https://api.weixin.qq.com/sns/jscode2session
     */
    @GetMapping("/wxLogin")
    public Map<String,String> wxLogin(@RequestParam(name = "code",required = true) String code){
        //小程序登录参数Get请求
        String openidParams = "appid=" + WxDataConfigure.appId + "&secret=" + WxDataConfigure.secret + "&js_code=" + code + "&grant_type=" + "authorization_code";
        String openidUrl = "https://api.weixin.qq.com/sns/jscode2session";
        //获取接口调用凭证参数Get请求
        String accessTokenParams = "appid=" + WxDataConfigure.appId + "&secret=" + WxDataConfigure.secret + "&grant_type=" + "client_credential";
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
        //http请求微信服务器
        String openIdResult = HttpRequest.sendGet(openidUrl, openidParams);
        String accessTokenResult = HttpRequest.sendGet(accessTokenUrl, accessTokenParams);
        JSONObject openIdJson = JSONObject.parseObject(openIdResult);
        JSONObject accessTokenJson = JSONObject.parseObject(accessTokenResult);
        //获取openId
        String openid =(String) openIdJson.get("openid");
        //会话秘钥
        String session_key =(String) openIdJson.get("session_key");
        //获取到的凭证
        String access_token =(String) accessTokenJson.get("access_token");
        Integer expiresIn =(Integer) accessTokenJson.get("expires_in");

        Map<String, String> infoMap = new HashMap<>();
        infoMap.put("openid",openid);
        infoMap.put("session_key",session_key);
        infoMap.put("access_token",access_token);
        infoMap.put("expiresIn",expiresIn.toString());
        return infoMap;
    }
}

一个在学习的开发者,勿喷,欢迎交流

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot微信小程序授权登录 的相关文章

  • 10071 - Back to High School Physics

    Back to High School Physics Time limit 3 000 seconds A partical 电 质点 has inital velocity and accerleration 初速度与加速度 If it
  • SQL6 查找学校是北大的学生信息

    描述 题目 现在运营想要筛选出所有北京大学的学生进行用户调研 请你从用户信息表中取出满足条件的数据 结果返回设备id和学校 示例 user profile id device id gender age university provinc
  • Linux--消息队列

    目录 一 线程和进程的概念 1 线程 2 进程 3 ipcs 二 消息队列代码 写消息 man msgget返回值问题 添加消息队列 man msgsnd 运行代码 运行结果图 进程和消息的状态 三 消息队列代码 读消息 b c读取消息 执
  • 微信公众号html教程,公众号排版简易教程

    微信公众号文章排版流程 1 将文章转换成Markdown格式 2 使用Typora渲染Markdown格式 3 使用印象笔记 生成图表 流程图 时序图等 并转换成图片 4 将Markdown格式转换为Html格式 5 将Html格式内容复制
  • 企业微信开始代开发应用 配置代开发应用回调URL

    用到的php版本是7 4 开发时间 2022 11 2 在做公司的项目时因为企业微信的更新 同一个服务器ip不能在多个企业项目中出现否则就会被判定为第三方服务商 所以新建应用时只能新建代开发应用 在配置回调的时候走了很多坑 在这里梳理一下
  • Dialog DA14585——基本硬件资源配置

    GPIO DA14585共有3中类型的封装 WLCSP34pin QFN40pin QFN48pin 除去专用的RST GND XTAL ANT VBAT脚后 分别有14 25 32个IO口可用 目前最常用的封装类型是QFN40 处理单元
  • ssh key创建本地和git的安全连接 && ssh key的创建与github/gitlab中ssh key的添加

    如未创建ssh key会报该问题 The authenticity of host can t be established Permission denied publickey ssh key的作用 创建本地和gitlab的安全连接 S

随机推荐

  • 从特效入手,深入了解CSS(二):鼠标 hover 特效

    不建议跳跃阅读 这篇文章将从头开始介绍如何实现一个特效 中间偶尔会穿插一些css3或平时接触不多的css属性 首先看一看这一期的特效 HTML部分 h1 Hover Me h1 CSS 部分 首先通过grid布局的place content
  • 一文搞定java8中的重要特性

    文章目录 Lambda表达式 函数式接口 四大内置函数接口 接口的默认方法和静态方法 方法引用 重复注解 更好的类型推断 拓宽注解的应用场景 Optional Stream Date Time API Base64 并行数组 并发性 JVM
  • Windows SDK与Platform SDK的区别

    原文URL http forums microsoft com MSDN ShowPost aspx PostID 1986681 SiteID 1 概述 Windows SDK已经取代了Platform SDK Platform SDK已
  • 使用Yolov5+Pytorch训练自定义目标检测模型

    一 简介 使用Pytorch Yolov5和OpenCV 完成目标检测模型的训练和部署 项目的两个功能 1 Yolov5离线文件夹 主要是为了照顾国内的网络环境 文件夹不仅包含了https github com ultralytics yo
  • 物联网(java版本)臻识摄像头+本地实时显示视频

    部分代码显示 package com xdnnaovideo videoservice listenermessage import com google gson Gson import com xdnnaovideo videoserv
  • stm32毕设分享 stm32老人跌倒检测预防系统

    文章目录 0 前言 1 整体设计 2 硬件电路 3 软件设计 4 跌倒检测算法 5 关键代码 6 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹
  • 最新版的配音软件--- tts-vue 软件 下载安装成功过程

    目录 本次软件是 Loker 制作 感谢作者的无私奉献 软件视频效果 软件图片效果 1 电脑版的tts vue 软件下载链接以及说明 2 tts vue 网站在线转换链接 3 tts vue 软件 功能简介 截至最新版本 已实现的功能 安装
  • gitlab--基础--5.1--CICD--介绍

    gitlab 基础 5 1 CICD 介绍 1 什么是CICD 1 1 CI 持续集成 Continuous Integration 1 1 1 持续集成 将各个开发人员的工作集合到一个代码仓库中 主要目的是尽早发现集成错误 使团队更加紧密
  • 关于退出进程的几种方式

    创建于 2012 08 27 迁移自个人的百度空间 HUP 是让进程挂起 睡眠 kill 杀掉进程 term 正常的退出进程 kill HUP pid pid 是进程标识 如果想要更改配置而不需停止并重新启动服务 请使用该命令 在对配置文件
  • 深入理解MyBatis一级缓存和二级缓存【超详细源码解析】

    视频地址 https www bilibili com video BV1nP411A7Gu MyBatis的缓存是一个常见的面试题 一级缓存的作用域为何是 sqlSession 二级缓存的作用域为何是 mapper 怎么理解 一 二级缓存
  • Go实现单例模式

    非线程安全的单例模式 type Singleton struct var instance Singleton func GetInstance Singleton if instance nil instance Singleton re
  • 【待续】【UE4笔记】 L10地形编辑器

    一 地形界面 包含了管理 雕刻和描画功能 1 创建新项 2 雕刻 改变地形高度 顶点位置 3 描画 分层地形材质 二 编辑样条 调节参数 添加材质 效果如下
  • 极限多标签学习综述(Extreme Multi-label Learning)

    A Survey on Extreme Multi label Learning 先给地址 https arxiv org abs 2210 03968 博主曾整理过Multi Label Image Classification 多标签图
  • Docker下安装SVN

    1 搜索svn镜像 root VM 0 6 centos docker search svn 2 拉取svn server的docker镜像 root VM 0 6 centos docker pull docker io garethfl
  • Stable Diffusion Webui源码剖析

    1 关键python依赖 1 xformers 优化加速方案 它可以对模型进行适当的优化来加速图片生成并降低显存占用 缺点是输出图像不稳定 有可能比不开Xformers略差 2 GFPGAN 它是腾讯开源的人脸修复算法 利用预先训练号的面部
  • 分布式--redis基本数据结构及使用

    文章目录 redis常用5种数据结构 字符串常用操作 字符串使用场景 1 单值缓存 session共享等 2 对象缓存 3 简单的分布式锁 4 计数器 5 全局唯一序列号 hash结构常用操作 hash结构的使用场景 1 对象缓存 2 购物
  • SpringBoot+Vue如何写一个HelloWorld

    一 SpringBoot介绍 Spring Boot是一个用于创建独立且可执行的Spring应用程序的框架 它简化了基于Spring框架的应用程序的开发过程 并提供了一种快速和简便的方式来构建Java应用程序 Spring Boot提供了自
  • 5. 智能指针(等后续

    指针本质上是一个内存地址索引 代表了一块内存区域 能够直接读写内存 因为指针完全映射了计算机硬件 所以操作效率高 是C C 高效的根源 但是指针也会产生访问无效数据 指针越界或者内存分配不及时等导致的运行错误 内存泄漏 资源丢失等一系列问题
  • 最新Keil MDK下载安装

    百度网盘下载 Keil MDK MDK5 38a https pan baidu com s 1REHRICabWMn0gHp8bgroWQ pwd 1122 MDK5 37 https pan baidu com s 1eA5cSpvCY
  • SpringBoot微信小程序授权登录

    SpringBoot微信小程序授权登录 一 appId 1 1 自己是管理者 微信公众平台 申请或登录自己的微信小程序 在开发者管理中即可看到 2 2 自己是开发者 让管理员将自己加入到小程序开发者管理中 用管理者提供的appId和secr