【Springboot】整合wxjava实现 微信小程序:授权登录

这篇具有很好参考价值的文章主要介绍了【Springboot】整合wxjava实现 微信小程序:授权登录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。



提示:以下是本篇文章正文内容,下面案例可供参考

一、wxjava是什么

WxJava - 微信开发 Java SDK,支持微信支付、开放平台、公众号、企业号/企业微信、小程序等的后端开发。
官方的gitee仓库地址
官方的github仓库地址
官方的关于微信小程序的demo

二、使用步骤

1.引入依赖

导入wxjava的maven依赖

<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>weixin-java-miniapp</artifactId>
  <version>4.3.0</version>
</dependency>

2.配置yml

wx:
  miniapp:
    configs:
      - appid: #微信小程序的appid
        secret: #微信小程序的Secret
        token: #微信小程序消息服务器配置的token
        aesKey: #微信小程序消息服务器配置的EncodingAESKey
        msgDataFormat: JSON

3.小程序的配置

WxMaProperties 用于读取yml配置的信息

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;

@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxMaProperties {

    private List<Config> configs;

    @Data
    public static class Config {
        /**
         * 设置微信小程序的appid
         */
        private String appid;

        /**
         * 设置微信小程序的Secret
         */
        private String secret;

        /**
         * 设置微信小程序消息服务器配置的token
         */
        private String token;

        /**
         * 设置微信小程序消息服务器配置的EncodingAESKey
         */
        private String aesKey;

        /**
         * 消息格式,XML或者JSON
         */
        private String msgDataFormat;
    }

}

WxMaConfiguration

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Configuration
@EnableConfigurationProperties(WxMaProperties.class)
public class WxMaConfiguration {
    private final WxMaProperties properties;

    @Autowired
    public WxMaConfiguration(WxMaProperties properties) {
        this.properties = properties;
    }

    @Bean
    public WxMaService wxMaService() {
        List<WxMaProperties.Config> configs = this.properties.getConfigs();
        if (configs == null) {
            throw new WxRuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
        }
        WxMaService maService = new WxMaServiceImpl();
        maService.setMultiConfigs(
            configs.stream()
                .map(a -> {
                    WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
//                WxMaDefaultConfigImpl config = new WxMaRedisConfigImpl(new JedisPool());
                    // 使用上面的配置时,需要同时引入jedis-lock的依赖,否则会报类无法找到的异常
                    config.setAppid(a.getAppid());
                    config.setSecret(a.getSecret());
                    config.setToken(a.getToken());
                    config.setAesKey(a.getAesKey());
                    config.setMsgDataFormat(a.getMsgDataFormat());
                    return config;
                }).collect(Collectors.toMap(WxMaDefaultConfigImpl::getAppid, a -> a, (o, n) -> o)));
        return maService;
    }

    @Bean
    public WxMaMessageRouter wxMaMessageRouter(WxMaService wxMaService) {
        final WxMaMessageRouter router = new WxMaMessageRouter(wxMaService);
        router
            .rule().handler(logHandler).next()
            .rule().async(false).content("订阅消息").handler(subscribeMsgHandler).end()
            .rule().async(false).content("文本").handler(textHandler).end()
            .rule().async(false).content("图片").handler(picHandler).end()
            .rule().async(false).content("二维码").handler(qrcodeHandler).end();
        return router;
    }

    private final WxMaMessageHandler subscribeMsgHandler = (wxMessage, context, service, sessionManager) -> {
        service.getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
            .templateId("此处更换为自己的模板id")
            .data(Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("keyword1", "339208499")))
            .toUser(wxMessage.getFromUser())
            .build());
        return null;
    };

    private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {
        log.info("收到消息:" + wxMessage.toString());
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
            .toUser(wxMessage.getFromUser()).build());
        return null;
    };

    private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
            .toUser(wxMessage.getFromUser()).build());
        return null;
    };

    private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {
        try {
            WxMediaUploadResult uploadResult = service.getMediaService()
                .uploadMedia("image", "png",
                    ClassLoader.getSystemResourceAsStream("tmp.png"));
            service.getMsgService().sendKefuMsg(
                WxMaKefuMessage
                    .newImageBuilder()
                    .mediaId(uploadResult.getMediaId())
                    .toUser(wxMessage.getFromUser())
                    .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        return null;
    };

    private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {
        try {
            final File file = service.getQrcodeService().createQrcode("123", 430);
            WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
            service.getMsgService().sendKefuMsg(
                WxMaKefuMessage
                    .newImageBuilder()
                    .mediaId(uploadResult.getMediaId())
                    .toUser(wxMessage.getFromUser())
                    .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        return null;
    };

}

这个是官方demo里面的,就是读取application.yml配置的信息进行初始化
其实里面很多内容你自己可以提取出来单独封装。后面会一一实现

4.后端的业务逻辑代码

controller

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.example.wxjava.common.result.R;
import com.example.wxjava.domain.dto.WxUserInfo;
import com.example.wxjava.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @author 成大事
 * @since 2022/7/27 22:44
 */
@Slf4j
@RestController
@RequestMapping("/wx/user")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class WxUserInfoController {
    private final WxMaService wxMaService;

    private final UserInfoService userInfoService;

    /**
     * 登陆接口
     */
    @GetMapping("/login")
    public R<WxMaJscode2SessionResult> login(@RequestParam("code") String code) {
        return userInfoService.login(code);
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @PostMapping("/getUserInfo")
    public R<WxMaUserInfo> getUserInfo(@RequestBody WxUserInfo userInfo) {
        return userInfoService.getUserInfo(userInfo);
    }
}

R 是我自己封装的统一返回类。大家可以自行设置返回类型

service

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.example.wxjava.common.result.R;
import com.example.wxjava.domain.dto.WxUserInfo;

/**
 * @author 成大事
 * @since 2022/7/27 22:47
 */
public interface UserInfoService {

    /**
     * 登录
     * @param code code
     * @return   WxMaJscode2SessionResult
     */
    R<WxMaJscode2SessionResult> login(String code);

    /**
     * 获取用户信息
     * @param userInfo  包含一些加密的信息
     * @return  WxMaUserInfo
     */
    R<WxMaUserInfo> getUserInfo(WxUserInfo userInfo);
}

impl

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.example.wxjava.common.result.R;
import com.example.wxjava.domain.dto.WxUserInfo;
import com.example.wxjava.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author 成大事
 * @since 2022/7/27 22:48
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class UserInfoServiceImpl implements UserInfoService {

    private final WxMaService wxMaService;

    /**
     * 登录
     * @param code code
     * @return   WxMaJscode2SessionResult
     */
    @Override
    public R<WxMaJscode2SessionResult> login(String code) {
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
            log.info(session.getSessionKey());
            log.info(session.getOpenid());
            //TODO 可以增加自己的逻辑,关联业务相关数据
            return R.ok(session);
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            return R.error(e.toString());
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }

    @Override
    public R<WxMaUserInfo> getUserInfo(WxUserInfo userInfo) {

        // 用户信息校验
        if (!wxMaService.getUserService().checkUserInfo(userInfo.getSessionKey(), userInfo.getRawData(), userInfo.getSignature())) {
            WxMaConfigHolder.remove();//清理ThreadLocal
            return R.error("user check failed");
        }

        // 解密用户信息
        WxMaUserInfo wxMaUserInfo = wxMaService.getUserService().getUserInfo(userInfo.getSessionKey(), userInfo.getEncryptedData(), userInfo.getIv());
        WxMaConfigHolder.remove();//清理ThreadLocal
        return R.ok(wxMaUserInfo);
    }
}

dto

这个其实是我测试的时候,一个对象,测试wxjava解密用户的信息。因为后端接收json对象需要对象或者map接收。

@Data
@Accessors(chain = true)
public class WxUserInfo implements Serializable {
    private String appid;
    private String sessionKey;
    /**
     * 签名信息
     */
    private String signature;
    /**
     * 非敏感的用户信息
     */
    private String rawData;
    /**
     * 加密的数据
     */
    private String encryptedData;
    /**
     * 加密密钥
     */
    private String iv;
}

目录结构
wxjava,微信小程序,spring boot,小程序

5.前端的业务逻辑代码

因为我前端也不是很好。所以就一个简单的demo
前端使用的是uniapp。大家可以去官网学习查看uniapp

新建项目

使用HBuilder X 新建一个uniapp的项目
wxjava,微信小程序,spring boot,小程序
然后在index.vue编写逻辑代码
大家可以将我这个拷贝过去。完美匹配我上面的后端代码

<template>
	<view class="content">
		<button @click="login()">微信登录</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello',
				sessionKey: ''
			}
		},
		onLoad() {

		},
		methods: {
			async login(){
				let that = this //保存当前作用域

				await uni.login({ //直接用这个调用微信接口
					onlyAuthorize:true,
					success:function(response){ // 用微信登录的话就要去微信开发工具
						console.log(response) //这里打印就说明接口调用成功了,然后看message login :ok
						//微信登录就完了,后面就是获取用户信息
						uni.request({
							url: 'http://localhost:8888/wx/user/login',
							data: {
								code: response.code
							},
							success(res) {
								console.log("sessionkey",res)
								that.sessionKey = res.data.data.sessionKey
							}
						})
						
					}
				})
				await uni.getUserProfile({
					desc:'测试用例',
					success:function(res){
						console.log("res",res)
						uni.request({
							url: 'http://localhost:8888/wx/user/getUserInfo',
							method: 'POST',
							dataType: 'json',
							data: {
								rawData: res.rawData,
								signature: res.signature,
								encryptedData: res.encryptedData,
								iv: res.iv,
								sessionKey: that.sessionKey
							},
							success(resc) {
								console.log("登录成功",resc)
							}
						})
					}
				})
				
			}
		}
	}
</script>

<style>

</style>

微信开发者工具

直接选择运行到微信开发者工具
wxjava,微信小程序,spring boot,小程序
然后在微信开发者工具
wxjava,微信小程序,spring boot,小程序
点击测试:
wxjava,微信小程序,spring boot,小程序
可以看到。调用起来了。
然后看控制台:
wxjava,微信小程序,spring boot,小程序
我们的第二个接口也完美调用。返回了用户的信息。虽然uniapp的接口可以直接获取用户的信息。
但是如果后端想要获取到这些信息。

  • 一种是前端发过来。
  • 一种是先登录。然后返回前端一个sessionkey。然后前端将rawData,signature,encryptedData,还有iv发过了。我们自己使用wxjava进行解析。

ok,到这儿就结束了。文章来源地址https://www.toymoban.com/news/detail-791372.html

到了这里,关于【Springboot】整合wxjava实现 微信小程序:授权登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot整合IJPay实现微信支付-V3---微信小程序

    微信支付适用于许多场合,如小程序、网页支付、但微信支付相对于其他支付方式略显麻烦,我们使用IJpay框架进行整合 JPay 让支付触手可及, 封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。不依赖任何第三方 mvc 框架,仅仅作为工具使用简单

    2024年02月02日
    浏览(55)
  • 前端uniapp+后端springboot 详细教程《实现微信小程序授权登录》(附完整前后端项目demo)

    微信小程序官方登录流程图: 参考微信小程序登录官网文档 1、前端技术栈 1.1、uniapp 使用uniapp构建一套代码多端使用的前端框架项目 1.2、前端封装工具 dateUtil.js: 功能: 1. 时间日期格式化 2. 传入日期是否和当前日期的比较 完整代码: requestUtil.js: 功能: 1. 定义公共的

    2024年02月14日
    浏览(37)
  • UNIAPP---实现微信小程序登录授权和手机号授权(uniapp做微信小程序)

    描述:uniapp开发小程序,先授权用户信息后再出现手机号授权的页面进行手机号授权。完成后返回上一页面并把信息存入后台以及前台缓存中,方便使用。 1.在uniapp的manifest.json进行微信小程序配置 2.封装request请求api.js(如果已封装可跳过) 3.封装微信授权登录以及获取手机

    2024年02月11日
    浏览(32)
  • SpringBoot整合微信小程序支付V3(支付、退款)

    微信支付开发前,需要先获取商家信息,包括商户号、AppId、证书和密钥。 获取商户号 微信商户平台 申请成为商户 = 提交资料 = 签署协议 = 获取商户号 获取AppID 微信公众平台 注册服务号 = 服务号认证 = 获取APPID = 绑定商户号 申请商户证书 登录商户平台 = 选择 账户中心 = 安

    2024年02月08日
    浏览(28)
  • 微信小程序实现授权登录及退出

    1.登录获取用户昵称,头像 2.创建云函数 右击新建文件夹cloud 在根目录project.config.json中添加: 右击文件夹cloud选择当前环境 右击文件夹cloud新建Node.js云函数,命名login 在新建文件夹login的index.js文件中: 右击login文件夹选择上传并部署:云端安装依赖(不上传node_modules),显

    2024年02月08日
    浏览(44)
  • SpringBoot 整合微信小程序微信支付V3 jsapi (支付、退款)

    最近的一个微信小程序项目里有用到微信支付,网上找的资料都是特别乱,看起来特别懵,结合了好多文章的内容,终于做了出来,可能我的这个博文看起来也是特别乱,但是是可以直接C走简单改一改就可以用的。(支付成功回调,和退款回调因为昨天刚在阿里申请的域名还

    2024年04月25日
    浏览(40)
  • 【微信小程序】实现授权登入---超详细讲解

               微信授权登录是指在使用某些第三方网站或应用时,用户可以选择使用自己的微信账号进行登录和验证身份。通过微信授权登录,用户可以免去繁琐的注册流程,只需点击授权按钮,即可使用自己的微信账号进行登录。当用户选择使用微信授权登录时,他们会

    2024年02月05日
    浏览(34)
  • SpringBoot整合微信小程序登录获取手机号并解密

    SpringBoot+微信小程序  文章目录: 一、小程序登录获取手机号的流程 二、pom导入所需的依赖包 三、接收微信小程序的参数 四、后端发请求的util工具方法 五、获取手机号的接口 六、请求接口获取的phone_info信息 1.前端请求getPhoneNumber方法获取code传给后端接口; 2.后端接口通过

    2024年02月09日
    浏览(43)
  • 结合若依框架实现微信小程序授权登录

    通过若依框架实现微信小程序的授权登录。 原视频链接: https://www.bilibili.com/video/BV1iM411E7RE/?spm_id_from=333.337.search-card.all.clickvd_source=c15794e732e28886fefab201ec9c6253 下载 ruoyi-vue 代码 https://gitee.com/y_project/RuoYi-Vue 下载 ruoyi-app 代码 https://gitee.com/y_project/RuoYi-App 流程图如下: app 模块配

    2023年04月25日
    浏览(28)
  • 微信小程序---微信授权弹窗实现(组件,需要地方直接调用即可)

     在资源处下载后 在调用页面 json: wxml: js: 1、先判断是否已经登录,未登录直接调用show_empower:true即可弹出登录授权框 2、点击授权会请求获取手机号码,通过手机号码请求后台数据,若登录成功后 3、在页面调用return_login(e)方法,判断e携带的值是否请求成功。 4、若成

    2024年02月12日
    浏览(76)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包