在网上很难搜索到若依来整合微信小程序登录的功能,自己就通过自己的理解整合了一下。这也是很久以前写的了,只是实现了功能,但登录逻辑不太好,改动也比较大。现在会看,感觉应该可以直接用若依注册用户接口来做微信小程序登录的功能。因为考研了,不想再去想改代码了,就把之前自己写的登录功能分享出来,仅供参考,如果用于生产环境可能不太好,自己用着玩吧。自己也可以看看用若依注册接口能不能实现。

注:因为写的时间太长了,下面的不知道粘的全不全,有小的问题可以自己改改

1.在ruoyi-admin 模块中的resource下的applicat.yml中加入配置

wx:
  appid: xxxxxxx
  secret: xxxxxxx
// 这里我做了个默认头像的url
  universalAvatar: xxxxxx

2. 在你创建的业务模块下引入https请求依赖

<!-- http请求工具类 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.13</version>
        </dependency>

3. 创建一个实体类(这里我用了Lombok注解)

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class WxInfo {
    /**
     * 临时码
     */
    private String code;
    /**
     * 昵称
     */
    private String nickName;
    /**
     * 头像
     */
    private String avatarUrl;

}

4.修改实体这个包下的(package com.ruoyi.common.core.domain.model;)

public class RegisterBody extends LoginBody
{
    /**
     * 用户名
     */
    private String username;

    /**
     * 用户密码
     */
    private String password;

    @Override
    public String toString() {
        return "RegisterBody{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public void setPassword(String password) {
        this.password = password;
    }

    public RegisterBody(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public RegisterBody() {
    }
}

5. 创建controller(记得在springsecurity 配置中放开微信登录的接口)

@RestController
public class WxLoginController {
    protected final Logger log = LoggerFactory.getLogger(this.getClass());
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private ISysUserService userService;
    @Resource
    private TokenService tokenService;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private SysUserMapper userMapper;

    @Value("${wx.appid}")
    private String appId;
    @Value("${wx.secret}")
    private String secret;
    @Value(("${wx.universalAvatar}"))
    private String universalAvatar;

    @PostMapping("/wxLogin")
    public AjaxResult wechatLogin(@RequestBody WxInfo wxInfo) {
        String code = wxInfo.getCode();
        if(code == null || "".equals(code)) {
            return AjaxResult.error("登录失败,请联系管理员");
        }
        String url = "https://api.weixin.qq.com/sns/jscode2session?" + "appid=" +
                appId +
                "&secret=" +
                secret +
                "&js_code=" +
                code +
                "&grant_type=authorization_code";
        // 创建client请求
        CloseableHttpClient client = HttpClientBuilder.create().build();
        // 构建get请求
        HttpGet get = new HttpGet(url);
        // 发送请求
        CloseableHttpResponse response = null;
        AjaxResult objectJsonResult = null;
        try {
            response = client.execute(get);
            assert response != null;
            log.info("请求响应码:{}",response.getStatusLine().getStatusCode());
            String result = EntityUtils.toString(response.getEntity());
            log.info("请求相应结果:{}",result);
            JSONObject jsonObject = JSON.parseObject(result);
            String openid = jsonObject.getString("openid");
            log.info("小程序唯一标识:{}", openid);
            String token = wxLogin(openid, openid, wxInfo.getNickName(), wxInfo.getAvatarUrl());
            // 查询用户角色信息
            List<String> roles = sysUserRoleMapper.selectUserRoleInfoByOpenId(openid);
            Map<String, Object> map = new HashMap<>(2);
            map.put("token", token);
            map.put("roles", roles);
            return AjaxResult.success(map);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 微信登录接口
     * @param username oppenId
     * @param password oppenId
     * @return token
     */
    public String wxLogin(String username, String password, String nickName, String avatarUrl)
    {
        SysUser sysUser = userService.selectUserByUserName(username);
        if (ObjectUtil.isEmpty(sysUser)) {
            // 注册用户
            log.info("微信用户不存在,注册中...");
            RegisterBody loginBody = new RegisterBody(username, password);
            Long userId = register(loginBody, nickName, avatarUrl);
            // 分配角色
            SysUserRole userRole = new SysUserRole();
            userRole.setRoleId(2L);
            userRole.setUserId((long) userId);
            int res = sysUserRoleMapper.batchUserRole(Collections.singletonList(userRole));
            if (res <= 0) {
                throw new CrudException("用户角色分配失败!");
            }
        }
        log.info("微信用户信息验证...");

        // 如果账户已经删除,则进行恢复
        if (!ObjectUtil.isEmpty(sysUser) && sysUser.getDelFlag().equals("2")) {
            SysUser updateUser = new SysUser();
            Long userId = sysUser.getUserId();
            updateUser.setUserId(userId);
            updateUser.setDelFlag("0");
            int userResult = userMapper.updateUser(updateUser);
            if (userResult <= 0) {
                throw new CrudException("用户登录信息恢复失败");
            }
            // 分配角色
            SysUserRole userRole = new SysUserRole();
            userRole.setRoleId(2L);
            userRole.setUserId((long) userId);
            int roleResult = sysUserRoleMapper.batchUserRole(Collections.singletonList(userRole));
            if (roleResult <= 0) {
                throw new CrudException("用户角色分配失败!");
            }
        }
        // 用户验证
        Authentication authentication = null;
        try
        {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        } finally {
            AuthenticationContextHolder.clearContext();
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());

        //更新用户信息
        if (!StringUtils.isEmpty(nickName) || !StringUtils.isEmpty(avatarUrl)) {
            SysUser updateUser = new SysUser();
            updateUser.setUserId(loginUser.getUserId());
            if (!StringUtils.isEmpty(nickName)) {
                updateUser.setNickName(nickName);
            }
            if (!StringUtils.isEmpty(avatarUrl)) {
                updateUser.setAvatar(avatarUrl);
            }
            int res = userMapper.updateUser(updateUser);
            if (res <= 0) {
                throw new CrudException("更新用户信息失败");
            }
        }
        // 生成token
        return tokenService.createToken(loginUser);
    }

    /**
     * 注册
     */
    public Long register(RegisterBody registerBody, String nickName, String avatarUrl)
    {
        String username = registerBody.getUsername(), password = registerBody.getPassword();
        Long userId = 0L;
        if (StringUtils.isEmpty(username)) {
            throw new CrudException("用户名不能为空");
        } else if (StringUtils.isEmpty(password)) {
            throw new CrudException("用户密码不能为空");
        } else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(username))) {
            throw new CrudException("保存用户'" + username + "'失败,注册账号已存在");
        } else {
            SysUser sysUser = new SysUser();
            sysUser.setUserName(username);
            sysUser.setNickName(StringUtils.isEmpty(nickName) ? "微信用户" : nickName);
            sysUser.setAvatar(StringUtils.isEmpty(avatarUrl) ? universalAvatar : avatarUrl);
            sysUser.setPassword(SecurityUtils.encryptPassword(registerBody.getPassword()));
            sysUser.setRoleId(2L);
            boolean flag = userService.registerUser(sysUser);
            if (!flag)
            {
                throw new CrudException("注册失败,请联系系统管理人员");
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER,
                        MessageUtils.message("user.register.success")));
            }
            return sysUser.getUserId();
        }
    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     */
    public void recordLoginInfo(Long userId)
    {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
        sysUser.setLoginDate(DateUtils.getNowDate());
        userService.updateUserProfile(sysUser);
    }

}

6.新增查询方法(也就是上面要用到的)

// 查询用户角色信息
List<String> roles = sysUserRoleMapper.selectUserRoleInfoByOpenId(openid)

select
            r.role_name
        from
            sys_user u,
            sys_role r,
            sys_user_role ur
        where
            u.del_flag = '0'
          and
            u.user_name = #{userName}
          and
            u.user_id = ur.user_id
          and
            r.role_id = ur.role_id
Logo

快速构建 Web 应用程序

更多推荐