结合ruoyi-cloud和ruoyi-app实现微信小程序的授权登录

2023-11-09

原视频链接

https://www.bilibili.com/video/BV1mg4y1s75r/?spm_id_from=333.337.search-card.all.click&vd_source=c15794e732e28886fefab201ec9c6253

1 前言

结合RuoYi-CloudRuoYi-App实现微信小程序的授权登录。
之前讲过前后端分离版的授权登录,逻辑大致一致,不同点有:

  • 微信头像和昵称的获取方式。由于最新的本地库通过getUserProfilegetUserInfo获取不到用户头像和昵称。采用头像昵称填写功能。(备注:https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01
  • 微服务端采用OpenFeign进行远程调用,不会远程调用的粉丝,可以学习一下。Feign的底层是Spring3.0RestTemplate,若依的RestTemplate又借助于OkHttp。相对于Feign本身来讲,OpenFeign是支持Spring MVC的注解的,用起来非常方便

1.1 环境准备

1.2 登录流程图

在这里插入图片描述

2 小程序代码

  • 微信开发者工具基础库用的2.30.*
  • app模块配置微信登录
    在这里插入图片描述
  • 使用自己的appid
    在这里插入图片描述

2.1 RuoYi-App编辑api/login.js

  • 登录、退出接口路径加/auth
  • 获取用户信息接口路径加/system
  • 获取验证码接口路径换成/code
import request from '@/utils/request'

// 登录方法
export function login(username, password, code, uuid) {
  const data = {
    username,
    password,
    code,
    uuid
  }
  return request({
    'url': '/auth/login',
    headers: {
      isToken: false
    },
    'method': 'post',
    'data': data
  })
}

// 获取用户详细信息
export function getInfo() {
  return request({
    'url': '/system/user/getInfo',
    'method': 'get'
  })
}

// 退出方法
export function logout() {
  return request({
    'url': '/auth/logout',
    'method': 'delete'
  })
}

// 获取验证码
export function getCodeImg() {
  return request({
    'url': '/code',
    headers: {
      isToken: false
    },
    method: 'get',
    timeout: 20000
  })
}

2.4 新增按钮微信授权登录

  • 在登录按钮下,新增微信授权登录按钮
<button @click="wxHandleLogin" class="login-btn cu-btn block bg-green lg round">微信授权登录</button>

2.6 新增wxHandleLogin方法获取code

// 微信登录
	async wxHandleLogin() {
			uni.getProvider({
				service:'Oauth',
				success: (res) => {
					console.log(res);
					if(res.provider.indexOf("WeiXin")){
						//登录
						uni.login({
							provider:'WeiXin',
							success: (loginRes) => {
							}
						})
					}
				}
			})
	}

2.9 创建sendWxLoginFormToLocalService方法

//向本地服务发起请求
	sendWxLoginFormToLocalService(){
				console.log("向后端发起请求" + this.wxLoginForm);
				this.$store.dispatch('wxLogin', this.wxLoginForm).then(() => {
				  this.$modal.closeLoading()
				}).catch(() => {

				})  
	}

3 微服务代码

3.5 auth服务TokenController添加接口wxLogin

    public R<?> wxLogin(@RequestBody WxLoginBody wxLoginBody){
        String code = wxLoginBody.getCode();

        //想微信服务器发送请求获取用户信息
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxAppConfig.getAppId() + "&secret=" + wxAppConfig.getAppSecret() + "&js_code=" + code + "&grant_type=authorizatinon_code";
        String res = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSONObject.parseObject(res);

        //获取session_key和openid
        String sessionKey = jsonObject.getString("session_key");
        String openid = jsonObject.getString("openid");

        if (StringUtils.hasText(openid)){
            // 如果解析成功,获取token
            LoginUser userInfo = sysLoginService.wxLogin(openid);
            // 获取登录token
            return R.ok(tokenService.createToken(userInfo));
        }else{
            return R.fail("微信登录失败!");
        }
    }

3.7 ruoyi-api模块新增远程调用

/**
     * 通过openid查询用户信息
     *
     * @param openid openid 用户唯一标识
     * @param source 请求来源
     * @return 结果
     */
    @GetMapping("/user/getInfoByOpenid/{openid}")
    public R<LoginUser> getInfoByOpenid(@PathVariable("openid") String openid, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

3.9 system服务SysUserController新增内部接口getInfoByOpenid和addWxUser

  • 数据库添加unionIdopenId
  • domain (SysUser)
/** unionId */
    private String unionId;

    /** openId */
    private String openId;
    
     public String getUnionId() {
        return unionId;
    }

    public void setUnionId(String unionId) {
        this.unionId = unionId;
    }

    public String getOpenId() {
        return openId;
    }

    public void setOpenId(String openId) {
        this.openId = openId;
    }
  • controller 层(SysUserController)
	/**
     * 根据openid获取当前用户信息
     */
    public R<LoginUser> getInfoByOpenid(@PathVariable("openid") String openid)
    {
        SysUser sysUser = userService.selectUserByOpenid(openid);
        LoginUser sysUserVo = new LoginUser();
        if (StringUtils.isNull(sysUser))
        {
            sysUserVo.setSysUser(null);
            return R.ok(sysUserVo);
        }
        return R.ok(sysUserVo);
    }
    
	/**
     * 新增微信用户信息
     */
    public R<SysUser> addWxUser(@RequestBody SysUser sysUser)
    {
        String username = sysUser.getUserName();
        userService.insertWxUser(sysUser);
        return R.ok(sysUser);
    }
  • service 层(SysUserServiceImpl)
    接口:
	/**
     * 通过openid查询用户
     *
     * @param openid 用户唯一标识
     * @return 用户对象信息
     */
    public SysUser selectUserByOpenid(String openid);

	/**
     * 新增微信用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    public int insertWxUser(SysUser user);

实现类:

	/**
     * 通过openid查询用户
     *
     * @param openid 用户唯一标识
     * @return 用户对象信息
     */
    @Override
    public SysUser selectUserByOpenid(String openid)
    {
        return userMapper.selectUserByOpenid(openid);
    }

	/**
     * 新增微信用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public int insertWxUser(SysUser user)
    {
        // 新增用户信息
        return userMapper.insertUser(user);
    }

mapper 层 (SysUserMapper)

/**
     * 通过openid查询用户
     *
     * @param openid 用户唯一标识
     * @return 用户对象信息
     */
    public SysUser selectUserByOpenid(String openid);

mybatis.xml (SysUserMapper.xml)

u.union_id, u.open_id,

....
<select id="selectUserByOpenid" parameterType="String" resultMap="SysUserResult">
		<include refid="selectUserVo"/>
		where u.open_id = #{openId} and u.del_flag = '0'
	</select>
....
<insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
 		insert into sys_user(
 			<if test="userId != null and userId != 0">user_id,</if>
 			<if test="deptId != null and deptId != 0">dept_id,</if>
 			<if test="userName != null and userName != ''">user_name,</if>
 			<if test="nickName != null and nickName != ''">nick_name,</if>
 			<if test="email != null and email != ''">email,</if>
 			<if test="avatar != null and avatar != ''">avatar,</if>
 			<if test="phonenumber != null and phonenumber != ''">phonenumber,</if>
 			<if test="sex != null and sex != ''">sex,</if>
 			<if test="password != null and password != ''">password,</if>
 			<if test="status != null and status != ''">status,</if>
 			<if test="createBy != null and createBy != ''">create_by,</if>
 			<if test="remark != null and remark != ''">remark,</if>
			<if test="openId != null and openId != ''">open_id,</if>
			<if test="unionId != null and unionId != ''">union_id,</if>
 			create_time
 		)values(
 			<if test="userId != null and userId != ''">#{userId},</if>
 			<if test="deptId != null and deptId != ''">#{deptId},</if>
 			<if test="userName != null and userName != ''">#{userName},</if>
 			<if test="nickName != null and nickName != ''">#{nickName},</if>
 			<if test="email != null and email != ''">#{email},</if>
 			<if test="avatar != null and avatar != ''">#{avatar},</if>
 			<if test="phonenumber != null and phonenumber != ''">#{phonenumber},</if>
 			<if test="sex != null and sex != ''">#{sex},</if>
 			<if test="password != null and password != ''">#{password},</if>
 			<if test="status != null and status != ''">#{status},</if>
 			<if test="createBy != null and createBy != ''">#{createBy},</if>
 			<if test="remark != null and remark != ''">#{remark},</if>
			<if test="openId != null and openId != ''">#{openId},</if>
			<if test="unionId != null and unionId != ''">#{unionId},</if>
 			sysdate()
 		)
	</insert>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结合ruoyi-cloud和ruoyi-app实现微信小程序的授权登录 的相关文章

  • MySQL必知必会 学习笔记 第七章 数据过滤

    可用AND操作符给WHERE子句附加条件 SELECT columnName FROM tableName WHERE columnName1 1 AND columnName2 2 OR操作符指示MySQL匹配符合操作符任一端条件的行 S
  • 监听器

    监听器在JavaWeb开发中用得比较多 下面说一下监听器 Listener 在开发中的常见应用 一 统计当前在线人数 在JavaWeb应用开发中 有时候我们需要统计当前在线的用户数 此时就可以使用监听器技术来实现这个功能了 1 packag
  • vue3 在原型上挂载方法

    在vue3 中没有 this 不在是实例化查出来的vue对象 那怎么往原型挂在公用的方法呢 const app createApp App const test gt console log 我是测试函数触发的 return 测试成功 ap
  • nginx第三方模块---nginx-sticky-module的平滑升级

    nginx第三方模块 nginx sticky module的平滑升级 第一步 下载 下载地址 链接 https bitbucket org nginx goodies nginx sticky module ng downloads ta
  • 5个方面详解:AI产品运营必知的软硬件技术

    比算法更难得是算法的思想 比编程工具更难的是编程的思维 比做产品更难的是产品的梦想 本文主要从5个方面 详细阐述AI产品运营必知的软硬件技术 一 AI产品运营对基础关系的安排 1 智能软硬件与软件和硬件 在AI产品里没有纯粹单独的软件和硬件
  • 【SpringBoot应用篇】SpringBoot集成MinIO对象存储服务

    SpringBoot应用篇 SpringBoot集成MinIO对象存储服务 对象存储服务MinIO MinIO简介 MinIO特点 开箱使用 docker安装启动 管理控制台 快速入门 Java 上传文件到minio 配置访问权限 封装Mi

随机推荐

  • 计算机基础知识深入研究系列:定点数与浮点数

    插眼 总结 暂无 自己还没深入研究 留链接供以后参考 深入浅出浮点数 https blog csdn net cppptr article details 573372 硬件中的定点数与浮点数运算与相互转换 https blog csdn
  • Qt 官方资源下载地址

    1 所有Qt版本下载地址 http download qt io archive qt 2 所有Qt Creator下载地址 http download qt io archive qtcreator 3 所有Qt VS开发插件下载地址 h
  • CubeMX——F1和G0系列外部中断回调函数差异

    以前写代码 一些固定的代码总喜欢复制粘贴 然后在G0系列使用外部中断的时候 发现死活触发不了 一路检查了CubeMX的配置以及硬件连接 均发现没问题 然后发现G0系列的外部中断回调函数和F1系列的不一样 以下列举的是配置下降沿触发模式 主要
  • 怎么给input插入一个图片

    html部分
  • 强化学习笔记:连续控制 & 确定策略梯度DPG

    1 离散控制与连续控制 之前的无论是DQN Q learning A2C REINFORCEMENT SARSA什么的 都是针对离散动作空间 不能直接解决连续控制问题 考虑这样一个问题 我们需要控制一只机械手臂 完成某些任务 获取奖励 机械
  • C++生成随机字符串的程序

    include
  • set-cookie失效之坑

    最近做的一个微信公众号项目 打开网页登录的时候就会出现每次请求sessionid不一致的问题 先贴图 session是后台生成的 由于验证码信息是放了在session里面 每次的session不一致 导致没有办法从session里面拿到响应
  • springmvc整合freemarker以及前端的一些坑

    一 SpringMVC整合freemarker配置 1 引入相关jar包 html view plain copy
  • 【LVGL】ANIM(动画)学习

    animate 通用动画 过渡动画与通用动画的区别 过渡动画只有在状态发生改变时发生 通用动画可以在任意时刻进行 过渡动画支是样式 style 的一部分 通用动画和样式是相互独立的 实际上 过渡的底层也使用的是动画 创建动画 为了创建动画
  • 海康摄像头视频调用出错,Jni Error(app bug): accessed stale local reference解决办法

    项目中要在Android手机中调用海康摄像头拍摄的画面 在公司网管配置好了网络地址 不要与其他局域网内地址冲突 和端口 并激活摄像头设备后 通过SADPTool 海康提供的摄像头搜索工具 可以自动检索到当前局域网内已激活的设备 通过设备列表
  • 算法笔记:字符串编辑距离(Edit Distance on Real sequence,EDR)/ Levenshtein距离

    1 算法介绍 给定两个长度分别为n和m的轨迹tr1和tr2 最小距离的匹配阈值e 两条轨迹之间的EDR距离就是需要对轨迹tr1进行插入 删除或替换使其变为tr2的操作次数 动态规划的算法如下 红色的是还没有考虑的两个轨迹部分 黑色是已经考虑
  • VScode 头文件添加路径

    先用调试运行建立三 有的是四个 个json文件 具体的操作步骤可以 点击这里转载 包含头文件路径主要是两个文件 一个是task json和c cpp properties json文件 1先打开task json文件 然后找到这一栏 最下面
  • Jmeter 三种提取方式 —— 关联实例

    当请求之间有依赖关系 比如一个请求的入参是另一个请求返回的数据 这时候就需要用到关联处理 Jmeter中常用的关联方法 正则表达式提取器 XPath提取器 JSON提取器 regex n 匹配除换行符 n r 之外的任何单个字符 零次或多次
  • Linux——shell脚本的基础篇(变量定义、变量种类、变量操作)

    文章目录 一 变量的定义 二 变量名称的规范 三 使用变量 四 在shell脚本中的变量种类 五 字符的转译及变量的声明 六 变量值的传递 一 变量的定义 变量即在程序运行过程中它的值是允许改变的量 变量是用一串固定的字符来表示不固定的值的
  • 【二叉树】44 二叉树:度为2的结点个数

    问题描述 内容 1 请参照链表的ADT模板 设计二叉树并逐步完善的抽象数据类型 由于该环境目前仅支持单文件的编译 故将所有内容都集中在一个源文件内 在实际的设计中 推荐将抽象类及对应的派生类分别放在单独的头文件中 参考教材 课件 以及网盘中
  • 斜率优化

    如果转移方程中含有 既有i 的项又有j的项 往往可以考虑斜率优化 斜率优化的目标是将dp式转化为 y kx b 这种形式 P3195 HNOI2008 玩具装箱TOY 题意 有1 n个玩具需要打包 每个玩具的有其长度 可以一段区间一段区间地
  • 珍藏多年的各类资源网站分享给大家

    学习网站 素材巷 这个应该有少数人知道吧 是我近几年来第一次遇到这样的网站 一个专注于分享文字素材的分享平台 涵盖文学范围广 包含散文 小说 诗词 戏曲 科普 天文 地志 阴阳 医卜 僧道 技艺 高考作文等 网址 素材巷 文字写作素材分享平
  • Unity3d接入googleplay内购详细说明(二)

    因为本文内容比较多 整理花费时间比较长 故分几篇完成 以下为本文目录结构 方便查阅 Unity3d接入googleplay内购详细说明 一 引言 一 准备条件 二 谷歌开发者后台应用创建说明 Unity3d接入googleplay内购详细说
  • 《Python进阶系列》二:Python中的 for-else 语法

    for else 语法 你是否见过这个语法 for i in xxx pass else pass 是不是一脸懵逼 啊哈哈哈 事实上 在 Python 中 else不仅可以与 if搭配使用 还可以与 for结合 想不到吧 我们先来看一个例子
  • 结合ruoyi-cloud和ruoyi-app实现微信小程序的授权登录

    文章目录 1 前言 1 1 环境准备 1 2 登录流程图 2 小程序代码 2 1 RuoYi App编辑api login js 2 4 新增按钮微信授权登录 2 6 新增wxHandleLogin方法获取code 2 9 创建sendWx