基于若依框架的微信小程序登录

2023-11-19

一、用户表结构

CREATE TABLE `bus_user` (
  `user_id` varchar(32) COLLATE utf8mb4_bin NOT NULL COMMENT '用户id',
  `parent_id` varchar(32) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '父级id',
  `notice_content` varchar(30) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '姓名',
  `user_name` varchar(30) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '登录名',
  `nick_name` varchar(30) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '微信昵称',
  `user_type` varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '用户类型',
  `email` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '邮箱',
  `phone_number` varchar(30) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '电话号码',
  `sex` varchar(2) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '性别',
  `avatar` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '头像',
  `password` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '密码',
  `status` varchar(2) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '状态',
  `login_ip` varchar(128) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '登录IP',
  `login_date` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '登录日期',
  `wx_brand` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '设备品牌',
  `wx_model` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '设备型号',
  `wx_language` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '微信语言',
  `wx_version` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '微信版本',
  `wx_platform` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '操作系统',
  `wx_system` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '系统版本',
  `wx_sdk_version` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '基础库版本',
  `wx_location_enabled` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '位置权限',
  `wx_wifi_enabled` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'wifi权限',
  `open_id` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '微信唯一id',
  `union_id` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '小程序唯一id',
  `del_flag` varchar(1) CHARACTER SET utf8mb4 DEFAULT '0' COMMENT '删除标志',
  `remark` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '备注',
  `area_code` varchar(12) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '行政区划code',
  `create_by` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '创建人',
  `create_time` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '更新人',
  `update_time` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC COMMENT='用户信息表';

二、用户实体类

public class BusUser extends BaseEntity {
    private static final long serialVersionUID = 1L;

    /** 用户id */
    private String userId;

    /** 父级id */
    @Excel(name = "父级id")
    private String parentId;

    /** 姓名 */
    @Excel(name = "姓名")
    private String noticeContent;

    /** 登录名 */
    @Excel(name = "登录名")
    private String userName;

    /** 微信昵称 */
    @Excel(name = "微信昵称")
    private String nickName;

    /** 用户类型 */
    @Excel(name = "用户类型")
    private String userType;

    /** 邮箱 */
    @Excel(name = "邮箱")
    private String email;

    /** 电话号码 */
    @Excel(name = "电话号码")
    private String phoneNumber;

    /** 性别 */
    @Excel(name = "性别")
    private String sex;

    /** 头像 */
    @Excel(name = "头像")
    private String avatar;

    /** 密码 */
    @Excel(name = "密码")
    private String password;

    /** 状态 */
    @Excel(name = "状态")
    private String status;

    /** 登录IP */
    @Excel(name = "登录IP")
    private String loginIp;

    /** 登录日期 */
    @Excel(name = "登录日期")
    private String loginDate;

    /** 设备品牌 */
    @Excel(name = "设备品牌")
    private String wxBrand;

    /** 设备型号 */
    @Excel(name = "设备型号")
    private String wxModel;

    /** 微信语言 */
    @Excel(name = "微信语言")
    private String wxLanguage;

    /** 微信版本 */
    @Excel(name = "微信版本")
    private String wxVersion;

    /** 操作系统 */
    @Excel(name = "操作系统")
    private String wxPlatform;

    /** 系统版本 */
    @Excel(name = "系统版本")
    private String wxSystem;

    /** 基础库版本 */
    @Excel(name = "基础库版本")
    private String wxSdkVersion;

    /** 位置权限 */
    @Excel(name = "位置权限")
    private String wxLocationEnabled;

    /** wifi权限 */
    @Excel(name = "wifi权限")
    private String wxWifiEnabled;

    /** 微信唯一id */
    @Excel(name = "微信唯一id")
    private String openId;

    /** 小程序唯一id */
    @Excel(name = "小程序唯一id")
    private String unionId;

    /** 删除标志 */
    private String delFlag;

    /** 行政区划code */
    @Excel(name = "行政区划code")
    private String areaCode;

    /** 分润比例 */
    @Excel(name = "分润比例")
    private int scale;

    public void setUserId(String userId)
    {
        this.userId = userId;
    }

    public String getUserId()
    {
        return userId;
    }
    public void setParentId(String parentId)
    {
        this.parentId = parentId;
    }

    public String getParentId()
    {
        return parentId;
    }
    public void setNoticeContent(String noticeContent)
    {
        this.noticeContent = noticeContent;
    }

    public String getNoticeContent()
    {
        return noticeContent;
    }
    public void setUserName(String userName)
    {
        this.userName = userName;
    }

    public String getUserName()
    {
        return userName;
    }
    public void setNickName(String nickName)
    {
        this.nickName = nickName;
    }

    public String getNickName()
    {
        return nickName;
    }
    public void setUserType(String userType)
    {
        this.userType = userType;
    }

    public String getUserType()
    {
        return userType;
    }
    public void setEmail(String email)
    {
        this.email = email;
    }

    public String getEmail()
    {
        return email;
    }
    public void setPhoneNumber(String phoneNumber)
    {
        this.phoneNumber = phoneNumber;
    }

    public String getPhoneNumber()
    {
        return phoneNumber;
    }
    public void setSex(String sex)
    {
        this.sex = sex;
    }

    public String getSex()
    {
        return sex;
    }
    public void setAvatar(String avatar)
    {
        this.avatar = avatar;
    }

    public String getAvatar()
    {
        return avatar;
    }
    public void setPassword(String password)
    {
        this.password = password;
    }

    public String getPassword()
    {
        return password;
    }
    public void setStatus(String status)
    {
        this.status = status;
    }

    public String getStatus()
    {
        return status;
    }
    public void setLoginIp(String loginIp)
    {
        this.loginIp = loginIp;
    }

    public String getLoginIp()
    {
        return loginIp;
    }
    public void setLoginDate(String loginDate)
    {
        this.loginDate = loginDate;
    }

    public String getLoginDate()
    {
        return loginDate;
    }
    public void setWxBrand(String wxBrand)
    {
        this.wxBrand = wxBrand;
    }

    public String getWxBrand()
    {
        return wxBrand;
    }
    public void setWxModel(String wxModel)
    {
        this.wxModel = wxModel;
    }

    public String getWxModel()
    {
        return wxModel;
    }
    public void setWxLanguage(String wxLanguage)
    {
        this.wxLanguage = wxLanguage;
    }

    public String getWxLanguage()
    {
        return wxLanguage;
    }
    public void setWxVersion(String wxVersion)
    {
        this.wxVersion = wxVersion;
    }

    public String getWxVersion()
    {
        return wxVersion;
    }
    public void setWxPlatform(String wxPlatform)
    {
        this.wxPlatform = wxPlatform;
    }

    public String getWxPlatform()
    {
        return wxPlatform;
    }
    public void setWxSystem(String wxSystem)
    {
        this.wxSystem = wxSystem;
    }

    public String getWxSystem()
    {
        return wxSystem;
    }
    public void setWxSdkVersion(String wxSdkVersion)
    {
        this.wxSdkVersion = wxSdkVersion;
    }

    public String getWxSdkVersion()
    {
        return wxSdkVersion;
    }
    public void setWxLocationEnabled(String wxLocationEnabled)
    {
        this.wxLocationEnabled = wxLocationEnabled;
    }

    public String getWxLocationEnabled()
    {
        return wxLocationEnabled;
    }
    public void setWxWifiEnabled(String wxWifiEnabled)
    {
        this.wxWifiEnabled = wxWifiEnabled;
    }

    public String getWxWifiEnabled()
    {
        return wxWifiEnabled;
    }
    public void setOpenId(String openId)
    {
        this.openId = openId;
    }

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

    public String getUnionId()
    {
        return unionId;
    }
    public void setDelFlag(String delFlag)
    {
        this.delFlag = delFlag;
    }

    public String getDelFlag()
    {
        return delFlag;
    }
    public void setAreaCode(String areaCode)
    {
        this.areaCode = areaCode;
    }

    public String getAreaCode()
    {
        return areaCode;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
                .append("userId", getUserId())
                .append("parentId", getParentId())
                .append("noticeContent", getNoticeContent())
                .append("userName", getUserName())
                .append("nickName", getNickName())
                .append("userType", getUserType())
                .append("email", getEmail())
                .append("phoneNumber", getPhoneNumber())
                .append("sex", getSex())
                .append("avatar", getAvatar())
                .append("password", getPassword())
                .append("status", getStatus())
                .append("loginIp", getLoginIp())
                .append("loginDate", getLoginDate())
                .append("wxBrand", getWxBrand())
                .append("wxModel", getWxModel())
                .append("wxLanguage", getWxLanguage())
                .append("wxVersion", getWxVersion())
                .append("wxPlatform", getWxPlatform())
                .append("wxSystem", getWxSystem())
                .append("wxSdkVersion", getWxSdkVersion())
                .append("wxLocationEnabled", getWxLocationEnabled())
                .append("wxWifiEnabled", getWxWifiEnabled())
                .append("openId", getOpenId())
                .append("unionId", getUnionId())
                .append("delFlag", getDelFlag())
                .append("remark", getRemark())
                .append("areaCode", getAreaCode())
                .append("createBy", getCreateBy())
                .append("createTime", getCreateTime())
                .append("updateBy", getUpdateBy())
                .append("updateTime", getUpdateTime())
                .toString();
    }

}

三、登录时用到的SQL语句

①登录前查询用户信息是否存在
<select id="selectUserByPhone" resultMap="BusUserResult" parameterType="String">
        SELECT *
        FROM bus_user
        where phone_number = #{phoneNumber}
    </select>
  ②用户信息不存在时,新增用户
  <insert id="insertBusUser" parameterType="com.ldly.common.core.domain.entity.BusUser">
        insert into bus_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userId != null">user_id,</if>
            <if test="parentId != null">parent_id,</if>
            <if test="noticeContent != null">notice_content,</if>
            <if test="userName != null">user_name,</if>
            <if test="nickName != null">nick_name,</if>
            <if test="userType != null">user_type,</if>
            <if test="email != null">email,</if>
            <if test="phoneNumber != null">phone_number,</if>
            <if test="sex != null">sex,</if>
            <if test="avatar != null">avatar,</if>
            <if test="password != null">password,</if>
            <if test="status != null">status,</if>
            <if test="loginIp != null">login_ip,</if>
            <if test="loginDate != null">login_date,</if>
            <if test="wxBrand != null">wx_brand,</if>
            <if test="wxModel != null">wx_model,</if>
            <if test="wxLanguage != null">wx_language,</if>
            <if test="wxVersion != null">wx_version,</if>
            <if test="wxPlatform != null">wx_platform,</if>
            <if test="wxSystem != null">wx_system,</if>
            <if test="wxSdkVersion != null">wx_sdk_version,</if>
            <if test="wxLocationEnabled != null">wx_location_enabled,</if>
            <if test="wxWifiEnabled != null">wx_wifi_enabled,</if>
            <if test="openId != null">open_id,</if>
            <if test="unionId != null">union_id,</if>
            <if test="delFlag != null">del_flag,</if>
            <if test="remark != null">remark,</if>
            <if test="areaCode != null">area_code,</if>
            <if test="createBy != null">create_by,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateBy != null">update_by,</if>
            <if test="updateTime != null">update_time,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="userId != null">#{userId},</if>
            <if test="parentId != null">#{parentId},</if>
            <if test="noticeContent != null">#{noticeContent},</if>
            <if test="userName != null">#{userName},</if>
            <if test="nickName != null">#{nickName},</if>
            <if test="userType != null">#{userType},</if>
            <if test="email != null">#{email},</if>
            <if test="phoneNumber != null">#{phoneNumber},</if>
            <if test="sex != null">#{sex},</if>
            <if test="avatar != null">#{avatar},</if>
            <if test="password != null">#{password},</if>
            <if test="status != null">#{status},</if>
            <if test="loginIp != null">#{loginIp},</if>
            <if test="loginDate != null">#{loginDate},</if>
            <if test="wxBrand != null">#{wxBrand},</if>
            <if test="wxModel != null">#{wxModel},</if>
            <if test="wxLanguage != null">#{wxLanguage},</if>
            <if test="wxVersion != null">#{wxVersion},</if>
            <if test="wxPlatform != null">#{wxPlatform},</if>
            <if test="wxSystem != null">#{wxSystem},</if>
            <if test="wxSdkVersion != null">#{wxSdkVersion},</if>
            <if test="wxLocationEnabled != null">#{wxLocationEnabled},</if>
            <if test="wxWifiEnabled != null">#{wxWifiEnabled},</if>
            <if test="openId != null">#{openId},</if>
            <if test="unionId != null">#{unionId},</if>
            <if test="delFlag != null">#{delFlag},</if>
            <if test="remark != null">#{remark},</if>
            <if test="areaCode != null">#{areaCode},</if>
            <if test="createBy != null">#{createBy},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateBy != null">#{updateBy},</if>
            <if test="updateTime != null">#{updateTime},</if>
        </trim>
    </insert>
   ③用户信息存在且登录时,更新用户信息
   <update id="updateBusUser" parameterType="com.ldly.common.core.domain.entity.BusUser">
        update bus_user
        <trim prefix="SET" suffixOverrides=",">
            <if test="parentId != null">parent_id = #{parentId},</if>
            <if test="noticeContent != null">notice_content = #{noticeContent},</if>
            <if test="userName != null">user_name = #{userName},</if>
            <if test="nickName != null">nick_name = #{nickName},</if>
            <if test="userType != null">user_type = #{userType},</if>
            <if test="email != null">email = #{email},</if>
            <if test="phoneNumber != null">phone_number = #{phoneNumber},</if>
            <if test="sex != null">sex = #{sex},</if>
            <if test="avatar != null">avatar = #{avatar},</if>
            <if test="password != null">password = #{password},</if>
            <if test="status != null">status = #{status},</if>
            <if test="loginIp != null">login_ip = #{loginIp},</if>
            <if test="loginDate != null">login_date = #{loginDate},</if>
            <if test="wxBrand != null">wx_brand = #{wxBrand},</if>
            <if test="wxModel != null">wx_model = #{wxModel},</if>
            <if test="wxLanguage != null">wx_language = #{wxLanguage},</if>
            <if test="wxVersion != null">wx_version = #{wxVersion},</if>
            <if test="wxPlatform != null">wx_platform = #{wxPlatform},</if>
            <if test="wxSystem != null">wx_system = #{wxSystem},</if>
            <if test="wxSdkVersion != null">wx_sdk_version = #{wxSdkVersion},</if>
            <if test="wxLocationEnabled != null">wx_location_enabled = #{wxLocationEnabled},</if>
            <if test="wxWifiEnabled != null">wx_wifi_enabled = #{wxWifiEnabled},</if>
            <if test="openId != null">open_id = #{openId},</if>
            <if test="unionId != null">union_id = #{unionId},</if>
            <if test="delFlag != null">del_flag = #{delFlag},</if>
            <if test="remark != null">remark = #{remark},</if>
            <if test="areaCode != null">area_code = #{areaCode},</if>
            <if test="createBy != null">create_by = #{createBy},</if>
            <if test="createTime != null">create_time = #{createTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="scale != null">scale = #{scale},</if>
        </trim>
        where user_id = #{userId}
    </update>

四、微信用户登录验证

/**
     * 微信用户登录验证
     * @param mobile
     * @return
     * @throws UsernameNotFoundException
     */
    public UserDetails wxUserByMobile(String mobile) throws UsernameNotFoundException{
        BusUser busUser = busUserService.selectUserByPhone(mobile);
        if (StringUtils.isNull(busUser)){
            log.info("登录用户:{} 不存在.", mobile);
            throw new ServiceException("登录用户:" + mobile + " 不存在");
        }else if (UserStatus.DELETED.getCode().equals(busUser.getDelFlag())){
            log.info("登录用户:{} 已被删除.", mobile);
            throw new ServiceException("对不起,您的账号:" + mobile + " 已被删除");
        }else if (UserStatus.DISABLE.getCode().equals(busUser.getStatus())){
            log.info("登录用户:{} 已被停用.", mobile);
            throw new ServiceException("对不起,您的账号:" + mobile + " 已停用");
        }
        return new LoginUser(busUser);
    }

 public LoginUser(BusUser busUser) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyBeanProp(sysUser,busUser);
        this.busUser = busUser;
        this.user = sysUser;
    }
 public BusUser selectUserByPhone(String phoneNumber) {
        return busUserMapper.selectUserByPhone(phoneNumber);
    }

五、创建token令牌

public String createToken(LoginUser loginUser)
    {
        String token = IdUtils.fastUUID();
        loginUser.setToken(token);
        setUserAgent(loginUser);
        refreshToken(loginUser);

        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.LOGIN_USER_KEY, token);
        return createToken(claims);
    }

  /**
     * 令牌前缀    类名:Constants
     */
    public static final String LOGIN_USER_KEY = "login_user_key";

/**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    private String createToken(Map<String, Object> claims)
    {
        String token = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret).compact();
        return token;
    }

/**
     * 刷新令牌有效期
     *
     * @param loginUser 登录信息
     */
    public void refreshToken(LoginUser loginUser)
    {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
        // 根据uuid将loginUser缓存
        String userKey = getTokenKey(loginUser.getToken());
        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
    }

    /**
     * 设置用户代理信息
     *
     * @param loginUser 登录信息
     */
    public void setUserAgent(LoginUser loginUser)
    {
        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        String ip = IpUtils.getIpAddr();
        loginUser.setIpaddr(ip);
        loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
        loginUser.setBrowser(userAgent.getBrowser().getName());
        loginUser.setOs(userAgent.getOperatingSystem().getName());
    }
  private String getTokenKey(String uuid)
    {
        return CacheConstants.LOGIN_TOKEN_KEY + uuid;
    }

六、登录接口涉及方法

package com.ldly.web.controller.tool;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ldly.common.annotation.Log;
import com.ldly.common.core.controller.BaseController;
import com.ldly.common.core.domain.AjaxResult;
import com.ldly.common.core.domain.entity.BusUser;
import com.ldly.common.core.domain.entity.SysRole;
import com.ldly.common.core.domain.entity.SysUser;
import com.ldly.common.core.domain.model.LoginUser;
import com.ldly.common.core.domain.model.WxLoginBody;
import com.ldly.common.enums.BusinessType;
import com.ldly.common.utils.http.HttpUtils;
import com.ldly.common.utils.sign.Base64;
import com.ldly.framework.web.service.TokenService;
import com.ldly.framework.web.service.WxLoginService;
import com.ldly.system.service.IBusUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.*;

@RestController
@RequestMapping("/wx")
@Api(tags = "微信小程序的登录控制器")
public class WxLoginController extends BaseController {

    /**
     * 获取微信小程序AppID
     */
    @Value("${wechat.appId}")
    private String appId;

    /**
     * 获取微信小程序AppSecret
     */
    @Value("${wechat.secret}")
    private String secret;
    /**
     * 获取微信小程序grantType
     */
    @Value("${wechat.grantType}")
    private String grantType;


    @Autowired
    WxLoginService wxLoginService;
    @Autowired
    TokenService tokenService;
    @Autowired
    IBusUserService busUserService;



    @PostMapping("/code/{code}")
    public AjaxResult getCode(@PathVariable String code) {
        logger.info("【微信小程序登录接口---调用微信换openId接口】请求参数:{}", JSONObject.toJSONString(code));
        String res = HttpUtils.sendGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + secret + "&js_code=" + code + "&grant_type=" + grantType);
        JSONObject resJSON = JSONObject.parseObject(res);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("openId", resJSON.get("openid"));
        ajax.put("sessionKey", resJSON.get("session_key"));
        logger.info("【微信小程序登录接口---调用微信换openId接口】相应结果:{}",JSONObject.toJSONString(ajax));
        return ajax;
    }


    @PostMapping("/login")
    @Transactional
    public AjaxResult getOpenId(@RequestBody WxLoginBody loginBody) {
        logger.info("【微信小程序登录接口---验证用户信息】请求参数:{}",JSONObject.toJSONString(loginBody));
        JSONObject userinfo = getUserInfo(loginBody.getEncryptedData(), loginBody.getSessionKey(), loginBody.getIv());
        if (ObjectUtils.isEmpty(userinfo)) {
            return AjaxResult.error("信息解密失败,请重新登录");
        }
        loginBody.setMobile(userinfo.getString("phoneNumber"));
        System.out.println(userinfo.toJSONString());
        String token = wxLoginService.login(loginBody);
        //返回微信登陆者的个人信息
        BusUser busUser = busUserService.selectUserByPhone(loginBody.getMobile());
        AjaxResult ajax = AjaxResult.success();
        ajax.put("token", token);
        ajax.put("busInfo", busUser);
        logger.info("【微信小程序登录接口---验证用户信息】相依结果:{}",JSONObject.toJSONString(ajax));
        return ajax;
    }


    private JSONObject getUserInfo(String encryptedData, String sessionKey, String iv){
        try {
            // 被加密的数据
            byte[] dataByte = Base64.decode(encryptedData);
            // 加密秘钥
            byte[] keyByte = Base64.decode(sessionKey);
            // 偏移量
            byte[] ivByte = Base64.decode(iv);
            // 如果密钥不足16位,那么就补足
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            // 初始化
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return JSONObject.parseObject(result);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    @PostMapping("/login/validate")
    public AjaxResult validateWx(HttpServletRequest request) {
        logger.info("【根据token获取当前登录用户信息】");
        AjaxResult ajax = new AjaxResult();
        try{
            LoginUser user = tokenService.getLoginUser(request);
            if (user == null) {
                return AjaxResult.error("用户未登陆");
            }
            Map<String, Object> result = new HashMap<>();
            //返回微信登陆者的个人信息
            BusUser busUser = busUserService.selectUserByPhone(user.getUserId().toString());
            result.put("busInfo", busUser);
            //返回用户信息
            ajax = AjaxResult.success(result);
        }catch(Exception e){
            ajax = AjaxResult.error("error");
            logger.info("登录验证失败,错误信息:{}",JSONObject.toJSONString(e));
        }
        logger.info("【根据token获取当前登录用户信息】相应结果:{}", JSON.toJSONString(ajax));
        return ajax;
    }

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

基于若依框架的微信小程序登录 的相关文章

随机推荐

  • dede:list分页与控制文章标题显示字数

    关于dedecms分页 百度上也有许多教程 本人记性不好所以写个博客保存下来 pagesize控制每页显示条数 在 dede list 结束标签 后边写上 dede pagelist 标签即可 如何控制文章显示字 让溢出部分用 代替呢 其实
  • IPS与防火墙旁路部署

    一 防火墙旁路部署 实现防护功能的同时 可以完全不需改变用户的网络环境 并且可以避免设备对用户网络造成中断的风险 用于把设备接在交换机的镜像口或者接在 HUB 上 保证外网用户访问服务器的数据经过此交换机 并且设置镜像口的时候需要同时镜像上
  • iview+page封装+强制刷新

    前言 iview的page封装 缺点无法固定页码按钮数量 而且current的页面恢复选中第一个实现不了 这里动态写了强制刷新的方法 下面是组件cpage vue
  • 【Spring

    上篇 Spring 事件监听概述 对 Spring 事件监听的机制有了个基本的了解 本篇来详细的解读下Spring 的 事件监听机制 事件监听详解 ApplicationEvent ApplicationListener 基于注释 异步 排
  • 多态的实现

    多态 之前介绍过多态的概念就是基类引用派生类对象且和派生类有相同的同名覆盖函数 那么现在我们就具体讲讲怎么实现多态 类方法实现多态性有两种方法 1 方法重载 可以声明多个同名但参数个数 类型 和顺序不同的方法 编译时根据参数 个数 类型和顺
  • win环境下SSH key 配置

    从Gitlab上拉取代码报错 Warning Permanently added gitlab wang cn 47 94 8 13 ECDSA to the list of known hosts Connection closed by
  • windows下使用FFmpeg生成YUV视频文件并播放(通过命令的方式)

    一 YUV的定义 YUV是一种颜色编码方法 它跟我们常见的RGB格式区分开来 常使用在各个视频处理组件中 其中 Y 代表明亮度 U 和 V 代表其色度 视频播放器把市面上流行的MP4等格式文件的视频部分解码出来 得到的一般会是YUV格式的数
  • Java方法重写注意事项

    系原创 只为需要它的人 Java方法重写的几个要求 重写的方法与父类方法签名 方法名称和参数列表 相同 子类重写的方法访问修饰符范围不能低于父类 父类的私有方法不能被重写 static修饰的方法不能被重写 返回值类型 如果父类中方法返回值类
  • 解决mybatis一对多只能获取部分数据的问题

    需求 building表和position表 Building类中含有List positionList mybatis查询方法需要查询到所有的building和building中含有所有的position 问题 sql语句和一对多方法写的
  • SQL如何进行优化

    SQL优化 前言 对于初级程序开发工程师而言 SQL是很多人的弱项 为此我给大家来做一下总结 希望能够帮到你们 课程说明 1 对MySQL SQL优化方案做讲解 学习如何排查慢查询 SQL优化 分页查询优化 一页一页的往下面翻这种查询方式
  • 针对读写操作频繁的应用系统的LINUX调优设置

    在线签约系统调优 项目类型 限制型应用 需要频繁调用 进行签章 调用的 保存在 磁盘中 项目业务设计实现 这里简要说明一下业务流程 前端业务系统过来的请求通过Nignx进行分流 通过网关DSS 将各自的请求转发到相应的老 新签章系统进行处理
  • 小白学Redis系列:Redis持久化

    Redis作为缓存数据库 区别于常规数据库的地方就在于Redis将数据存储在内存中 而不是硬盘中 因此数据的IO就十分快速 非常适合一些电商网站等数据IO频繁的场景 当然 内存中的数据在掉电之后就会被清空 而Redis的持久化功能使得内存中
  • linux后台运行之screen和nohup

    linux后台运行之screen和nohup 3 1 nohup命令 如果你正在运行一个进程 而且你觉得在退出帐户时该进程还不会结束 那么可以使用nohup命令 该命令可以在你退出帐户 关闭终端之后继续运行相应的进程 nohup就是不挂起的
  • 进制及进制转换详解。原码、反码、移码,补码区别介绍。(通俗易懂)

    目录 前言 一 十进制 n进制 进制转换详解 1 先说说什么是进制 2 二进制介绍 3 十进制 n进制 进制转换详解 重点 十进制 gt n进制 2 8 16 n进制 2 8 16 gt 十进制 非十进制间的互相转化 二 原码 反码 移码
  • Python数据可视化 - 如何自定义Matplotlib图例?

    Python数据可视化 如何自定义Matplotlib图例 Matplotlib 是一个最常用的Python数据可视化库 它允许我们创建各种类型的图形 包括直方图 折线图 散点图 饼状图等 当我们绘制多个子图或多个曲线时 我们可能需要图例来
  • SpringBoot 整合 ElasticSearch

    整合前先理解几个概念 与关键字 开始前给大家推荐一款很火的刷题 面试求职网站 https www nowcoder com link pc csdncpt xiaoying java 索引
  • Java编程练习题:Demo96 - Demo105(多维数组)

    目录 Demo96 代数方面 两个矩阵相乘 编写两个矩阵相乘的方法 Demo97 距离最近的两个点 程序清单8 3给出找到二维空间中距离最近的两个点的程序 修改该程序 让程序能够找出在三维空间上距离最近的两个点 Demo98 最大的行和列
  • flink-addSource和addSink分别是kafka、自定义数据、mysql、hbase的java实现

    flink主程序 public class FinkTest public static void main String args throws Exception StreamExecutionEnvironment env Strea
  • Python 和 A-frame实现从图像创建 3D 模型--附完整示例代码

    介绍 虚拟现实是指由计算机生成的模拟 允许用户使用特殊耳机进行交互 简而言之 它是由计算机创建的另类现实 而耳机可以让人们沉浸在该现实中 根据 Allied Market Research 的数据 到 2026 年 VR 内容创作市场将达到
  • 基于若依框架的微信小程序登录

    一 用户表结构 CREATE TABLE bus user user id varchar 32 COLLATE utf8mb4 bin NOT NULL COMMENT 用户id parent id varchar 32 CHARACTE