0


若依Springboot实现小程序登录

若依Springboot整合微信小程序实现登录

前言

✅作者:TuNan

✨个人主页:图南的个人主页

😉欢迎关注🔎点赞😍收藏⭐留言💌

一、微信小程序官方登录流程图

在这里插入图片描述

主要的流程就是调用wx.getUserProfile向微信服务器发送请求获取code和其他的一些信息,然后再通过wx.login向我们的后台发送请求获取session_keyopenid等其他信息

二、个人实现登录流程

1️⃣首先去我们的微信公众号平台拿到AppId和AppSecret。等一下我们会用到😉

在这里插入图片描述

2️⃣数据库设计

在这里插入图片描述

CREATETABLE`user`(`pk_id`bigint(20)NOTNULLCOMMENT'主键',`nickname`varchar(50)DEFAULTNULLCOMMENT'用户昵称',`service_man_id`bigint(20)DEFAULTNULL,`avatarUrl`varchar(200)DEFAULTNULLCOMMENT'用户头像',`openid`varchar(50)DEFAULTNULL,`unionid`varchar(50)DEFAULTNULLCOMMENT'用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。',`create_time`datetimeDEFAULTCURRENT_TIMESTAMP,`update_time`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,PRIMARYKEY(`pk_id`)USINGBTREE,UNIQUEKEY`user_unionid_uindex`(`unionid`)USINGBTREE)ENGINE=InnoDBDEFAULTCHARSET=utf8 ROW_FORMAT=DYNAMIC;

这里service_man_id和unioinid可以不用

3️⃣Springboot后端

3.1 将我们刚才从微信公众号平台获取到的appld定义一个常量类

在这里插入图片描述

packagecom.ruoyi.gas.constant;/**
 * @Description 系统常量
 * @Author TuNan
 * @Date 2023/10/15
 */publicclassSystemConstant{/**
     * 应用唯一标识,在微信开放平台提交应用审核通过后获得
     */publicstaticfinalStringAPPLETS_APPID="wx98935fbf9774bf5a";/**
     * 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
     */publicstaticfinalStringAPPLETS_SECRET="adbecc45d036d4ba52aab8285c159216";}

3.2实体类

在这里插入图片描述

packagecom.ruoyi.gas.domain;importcom.baomidou.mybatisplus.annotation.TableField;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importlombok.Getter;importlombok.Setter;importlombok.experimental.Accessors;importjava.io.Serializable;/**
 * 移动端用户对象 gas_xcx_user
 *
 * @author TuNan
 * @date 2023-09-17
 */@Getter@Setter@TableName("user")@Accessors(chain =true)publicclassUserimplementsSerializable{privatestaticfinallong serialVersionUID =1L;@TableId("pk_id")privateLong pkId;/**
     * 用户昵称
     */@TableField("nickname")privateString nickname;/**
     * 用户头像
     */@TableField("avatarUrl")privateString avatarUrl;/**
     * 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
     */@TableField("unionid")privateString unionId;@TableField("openid")privateString openid;privateLongServiceManId;}

3.3 controller层

在这里插入图片描述

packagecom.ruoyi.gas.controller;importcom.ruoyi.gas.domain.dto.UserDTO;importcom.ruoyi.gas.domain.vo.ReWxUserInfoVO;importcom.ruoyi.gas.service.UserService;importorg.springframework.web.bind.annotation.*;importjavax.annotation.Resource;importjava.util.Map;/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author TuNan
 * @since 2023/10/13
 */@RestController@RequestMapping("/gas/user")publicclassUserController{@ResourceprivateUserService userService;/**
     * 微信小程序登录
     *
     * @param requestData 请求参数
     * @return ReWxUserInfoVO
     */@PostMapping("/getUserLoginByApplets")@SuppressWarnings("unchecked")// 用于抑制编译器产生警告信息。publicReWxUserInfoVOgetUserLoginByApplets(@RequestBodyMap<String,Object> requestData){String code =(String) requestData.get("code");Map<String,Object> userMap =(Map<String,Object>) requestData.get("user");UserDTO userDTO =newUserDTO();
        userDTO.setAvatarUrl((String) userMap.get("avatarUrl"));
        userDTO.setCity((String) userMap.get("city"));
        userDTO.setCountry((String) userMap.get("country"));
        userDTO.setGender((Integer) userMap.get("gender"));
        userDTO.setLanguage((String) userMap.get("language"));
        userDTO.setNickName((String) userMap.get("nickName"));System.out.println("userDTO = "+ userDTO);return userService.loginByWxApplets(code , userDTO);}}

3.4 服务层及实现

packagecom.ruoyi.gas.service;importcom.baomidou.mybatisplus.extension.service.IService;importcom.ruoyi.gas.domain.User;importcom.ruoyi.gas.domain.dto.UserDTO;importcom.ruoyi.gas.domain.vo.ReWxUserInfoVO;/**
 * <p>
 * 服务类
 * </p>
 *
 * @author TuNan
 * @since 2023-09-18
 */publicinterfaceUserServiceextendsIService<User>{/**
     * 微信登录 小程序版
     */ReWxUserInfoVOloginByWxApplets(String code,UserDTO userDTO);}
packagecom.ruoyi.gas.service.impl;importcn.dev33.satoken.stp.StpUtil;importcn.hutool.core.bean.BeanUtil;importcn.hutool.core.util.IdUtil;importcn.hutool.core.util.ObjectUtil;importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.ruoyi.common.core.domain.model.LoginUser;importcom.ruoyi.common.enums.DeviceType;importcom.ruoyi.common.helper.LoginHelper;importcom.ruoyi.gas.domain.User;importcom.ruoyi.gas.domain.dto.UserDTO;importcom.ruoyi.gas.domain.ro.AppletsWxLoginRO;importcom.ruoyi.gas.domain.vo.ReWxUserInfoVO;importcom.ruoyi.gas.mapper.UserMapper;importcom.ruoyi.gas.service.UserService;importcom.ruoyi.gas.utils.WxLoginUtil;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Service;/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xiahaike
 * @since 2023/10/13
 */@Service@Slf4jpublicclassUserServiceImplextendsServiceImpl<UserMapper,User>implementsUserService{@OverridepublicReWxUserInfoVOloginByWxApplets(String code,UserDTO userDTO){// 1.通过code 获取到用户的微信信息AppletsWxLoginRO getWxUserInfoRO =WxLoginUtil.toAppletsWxLogin(code);// 2.数据库对比 unionid 是否已有信息 如果没有就保持数据库QueryWrapper<User> queryWrapper =newQueryWrapper<>();// 3.通过查询pk_id 索引优化查询 无需回表查询用户信息 索引 openid
        queryWrapper.eq("openid", getWxUserInfoRO.getOpenid());User user =getOne(queryWrapper);
        log.info("数据库查询用户是否已有账号==空则没有==={}====", user);// 4.如果用户不存在则创建用户if(ObjectUtil.isEmpty(user)){long userId =IdUtil.getSnowflakeNextId();String nickName = userDTO.getNickName();save(newUser().setPkId(userId).setNickname(nickName).setOpenid(getWxUserInfoRO.getOpenid()).setAvatarUrl(userDTO.getAvatarUrl()).setServiceManId(0L));LoginUser loginUser =BeanUtil.toBean(newUser().setPkId(userId).setNickname(nickName),LoginUser.class);
            loginUser.setUserType("sys_user");
            loginUser.setUserId(IdUtil.getSnowflakeNextId());LoginHelper.loginByDevice(loginUser,DeviceType.XCX);returnnewReWxUserInfoVO().setPkId(userId).setNickname(nickName).setSession_key(getWxUserInfoRO.getSession_key()).setOpenid(getWxUserInfoRO.getOpenid()).setToken(StpUtil.getTokenValue()).setAvatarUrl(userDTO.getAvatarUrl()).setServiceManId(0L);}// 5.如果用户存在则直接登录LoginUser loginUser =BeanUtil.toBean(user,LoginUser.class);
        loginUser.setUserType("sys_user");
        loginUser.setUserId(IdUtil.getSnowflakeNextId());LoginHelper.loginByDevice(loginUser,DeviceType.XCX);returnnewReWxUserInfoVO().setPkId(user.getPkId()).setNickname(user.getNickname()).setAvatarUrl(user.getAvatarUrl()).setSession_key(getWxUserInfoRO.getSession_key()).setOpenid(getWxUserInfoRO.getOpenid()).setToken(StpUtil.getTokenValue()).setServiceManId(user.getServiceManId());}}

3.5微信登录工具包

packagecom.ruoyi.gas.utils;importcn.hutool.core.text.StrFormatter;importcn.hutool.http.HttpUtil;importcn.hutool.json.JSONUtil;importcom.ruoyi.gas.Enum.WxApiType;importcom.ruoyi.gas.constant.SystemConstant;importcom.ruoyi.gas.domain.ro.AppletsWxLoginRO;importlombok.extern.slf4j.Slf4j;/**
 * @Description 微信登录工具包
 * @Author TuNan
 * @Date 2023/10/16
 */@Slf4jpublicclassWxLoginUtil{/**
     *微信登录
     * @param code 前端请求获取=>微信code
     * @return void
     * @author zhangjunrong
     * @date 2022/12/19 20:16
     */publicstaticAppletsWxLoginROtoAppletsWxLogin(String code){//1.通过前端给的code获取openid和access_token还有unionidString getTokenOpenid =StrFormatter.format(WxApiType.APPLETS_GET_TOKEN_OPENID.getValue(),SystemConstant.APPLETS_APPID,SystemConstant.APPLETS_SECRET, code);String data =HttpUtil.get(getTokenOpenid);
        log.info("微信获取获取openid和unionid,返回结果======{}=====",data);//json=>bean//todo 获取用户信息失败 抛异常returnJSONUtil.toBean(data,AppletsWxLoginRO.class);}}

3.6 Ro及Vo

packagecom.ruoyi.gas.domain.ro;importlombok.Data;/**
 * @Description 微信用户基础信息
 * @Author TuNan
 * @Date 2023/10/16
 */@DatapublicclassWxUserInfoRO{/**
     * 用户昵称
     */privateString nickname;/**
     * 用户头像
     */privateString avatarUrl;/**
     * 用户微信统一标识
     */privateString unionid;privateString session_key;privateString openid;}
packagecom.ruoyi.gas.domain.ro;importlombok.Data;/**
 * @Description TODO
 * @Author TuNan
 * @Date 2023/09/18
 */@DatapublicclassAppletsWxLoginRO{/**
     *普通用户标识,对该公众帐号唯一
     */privateString openid;/**
     *用户在开放平台的唯一标识符
     */privateString unionid;privateString session_key;}
package com.ruoyi.gas.domain.vo;

import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @Description 返回前端微信个人信息
 * @Author TuNan
 * @Date 2023/9/17 15:27
 */
@Data
@Accessors(chain = true)
public class ReWxUserInfoVO {
    /**
     * 用户id
     */
    private Long pkId;

    /**
     * 用户昵称
     */
    private String nickname;

    /**
     * 用户头像
     */
    private String avatarUrl;

    private String unionid;

    private String session_key;

    private String openid;

    private String token;

    private Long ServiceManId;
}

以下就是我们后端的所有代码,接下来是小程序端的代码

4️⃣小程序实现

4.1首先我们在app.js中定义全局变量

在这里插入图片描述

// app.jsApp({globalData:{token:'',openid:null,sessionKey:null,serviceManId:0,pkId:0,// 用于判断用户是否登录}})

4.2 然后是我们在主页调用wx.logind的js代码

在这里插入图片描述

const app = getApp()
// 点击登录按钮login(){if(this.data.pkId !=0){
      Toast.fail("您已登录,请勿重复提交")}else{
      console.log('执行了登录操作');
      wx.getUserProfile({desc:'Wexin',// 这里应该是向微信发送请求获取用户名和头像success:(res)=>{this.setData({userInfo: res.userInfo
          })let user =this.data.userInfo // user里面保存从微信获取的信息(用户名和头像)// 向后台发送请求 将code、用户头像、用户名一起发送至后台
          console.log(user)
          wx.login({success:(res)=>{
              console.log(res)const code = res.code;
              wx.request({url: baseUrl +'/gas/user/getUserLoginByApplets',method:"POST",data:{
                  user,
                  code
                },success:(res)=>{// 后端返回的数据var Mydata = res.data
                  // 将从服务器获取的token、session_key等保存到globalData中
                  app.globalData.token = Mydata.token
                  app.globalData.session_key = Mydata.session_key
                  app.globalData.serviceManId = Mydata.serviceManId
                  app.globalData.openid = Mydata.openid
                  app.globalData.pkId = Mydata.pkId
                  // 将serviceId和pkid保存到当前页面中this.setData({serviceManId: app.globalData.serviceManId,pkId: res.data.pkId
                  });}})},})}})}},

在这里插入图片描述

到此我们所有流程就结束了🤞,出现以上效果说明就成功登录了😉


你好,我是博主

图南

,有问题可以留言评论或者私信我,大家一起交流学习!

不过都看到这里啦,点个赞吧👩‍💻

在这里插入图片描述


本文转载自: https://blog.csdn.net/qq_59008737/article/details/133960151
版权归原作者 Tunanna 所有, 如有侵权,请联系我们删除。

“若依Springboot实现小程序登录”的评论:

还没有评论