微服务项目:尚融宝(28)(后端搭建:实现用户登录(1))

本文涉及的产品
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,182元/月
简介: 微服务项目:尚融宝(28)(后端搭建:实现用户登录(1))

认清现实,放弃幻想,准备斗争


需求



dd62eb28ab03442eaf8c7cd17420092f.png


一、后端的接口



1、集成JWT


service-base中添加依赖


<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
</dependency>


2、JWT工具


service-base中添加util包


添加JwtUtils类


public class JwtUtils {
    private static long tokenExpiration = 24*60*60*1000;
    private static String tokenSignKey = "A1t2g3uigu123456";
    private static Key getKeyInstance(){
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] bytes = DatatypeConverter.parseBase64Binary(tokenSignKey);
        return new SecretKeySpec(bytes,signatureAlgorithm.getJcaName());
    }
    public static String createToken(Long userId, String userName) {
        String token = Jwts.builder()
                .setSubject("SRB-USER")
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                .claim("userId", userId)
                .claim("userName", userName)
                .signWith(SignatureAlgorithm.HS512, getKeyInstance())
                .compressWith(CompressionCodecs.GZIP)
                .compact();
        return token;
    }
    /**
     * 判断token是否有效
     * @param token
     * @return
     */
    public static boolean checkToken(String token) {
        if(StringUtils.isEmpty(token)) {
            return false;
        }
        try {
            Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    public static Long getUserId(String token) {
        Claims claims = getClaims(token);
        Integer userId = (Integer)claims.get("userId");
        return userId.longValue();
    }
    public static String getUserName(String token) {
        Claims claims = getClaims(token);
        return (String)claims.get("userName");
    }
    public static void removeToken(String token) {
        //jwttoken无需删除,客户端扔掉即可。
    }
    /**
     * 校验token并返回Claims
     * @param token
     * @return
     */
    private static Claims getClaims(String token) {
        if(StringUtils.isEmpty(token)) {
            // LOGIN_AUTH_ERROR(-211, "未登录"),
            throw new BusinessException(ResponseEnum.LOGIN_AUTH_ERROR);
        }
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(token);
            Claims claims = claimsJws.getBody();
            return claims;
        } catch (Exception e) {
            throw new BusinessException(ResponseEnum.LOGIN_AUTH_ERROR);
        }
    }
}



3、创建VO对象


service-core中创建登录对象


@Data
@ApiModel(description="登录对象")
public class LoginVO {
    @ApiModelProperty(value = "用户类型")
    private Integer userType;
    @ApiModelProperty(value = "手机号")
    private String mobile;
    @ApiModelProperty(value = "密码")
    private String password;
}



用户信息对象


@Data
@ApiModel(description="用户信息对象")
public class UserInfoVO {
    @ApiModelProperty(value = "用户姓名")
    private String name;
    @ApiModelProperty(value = "用户昵称")
    private String nickName;
    @ApiModelProperty(value = "头像")
    private String headImg;
    @ApiModelProperty(value = "手机号")
    private String mobile;
    @ApiModelProperty(value = "1:出借人 2:借款人")
    private Integer userType;
    @ApiModelProperty(value = "JWT访问令牌")
    private String token;
}



4、Controller


UserInfoController


@ApiOperation("会员登录")
@PostMapping("/login")
public R login(@RequestBody LoginVO loginVO, HttpServletRequest request) {
    String mobile = loginVO.getMobile();
    String password = loginVO.getPassword();
    Assert.notEmpty(mobile, ResponseEnum.MOBILE_NULL_ERROR);
    Assert.notEmpty(password, ResponseEnum.PASSWORD_NULL_ERROR);
    String ip = request.getRemoteAddr();
    UserInfoVO userInfoVO = userInfoService.login(loginVO, ip);
    return R.ok().data("userInfo", userInfoVO);
}



5、Service


接口:UserInfoService


UserInfoVO login(LoginVO loginVO, String ip);


实现:UserInfoServiceImpl


@Resource
private UserLoginRecordMapper userLoginRecordMapper;
@Transactional( rollbackFor = {Exception.class})
@Override
public UserInfoVO login(LoginVO loginVO, String ip) {
    String mobile = loginVO.getMobile();
    String password = loginVO.getPassword();
    Integer userType = loginVO.getUserType();
    //获取会员
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("mobile", mobile);
    queryWrapper.eq("user_type", userType);
    UserInfo userInfo = baseMapper.selectOne(queryWrapper);
    //用户不存在
    //LOGIN_MOBILE_ERROR(-208, "用户不存在"),
    Assert.notNull(userInfo, ResponseEnum.LOGIN_MOBILE_ERROR);
    //校验密码
    //LOGIN_PASSWORD_ERROR(-209, "密码不正确"),
    Assert.equals(MD5.encrypt(password), userInfo.getPassword(), ResponseEnum.LOGIN_PASSWORD_ERROR);
    //用户是否被禁用
    //LOGIN_DISABLED_ERROR(-210, "用户已被禁用"),
    Assert.equals(userInfo.getStatus(), UserInfo.STATUS_NORMAL, ResponseEnum.LOGIN_LOKED_ERROR);
    //记录登录日志
    UserLoginRecord userLoginRecord = new UserLoginRecord();
    userLoginRecord.setUserId(userInfo.getId());
    userLoginRecord.setIp(ip);
    userLoginRecordMapper.insert(userLoginRecord);
    //生成token
    String token = JwtUtils.createToken(userInfo.getId(), userInfo.getName());
    UserInfoVO userInfoVO = new UserInfoVO();
    userInfoVO.setToken(token);
    userInfoVO.setName(userInfo.getName());
    userInfoVO.setNickName(userInfo.getNickName());
    userInfoVO.setHeadImg(userInfo.getHeadImg());
    userInfoVO.setMobile(userInfo.getMobile());
    userInfoVO.setUserType(userType);
    return userInfoVO;
}


理清楚这里的业务逻辑:


1.先去查找用户是不是存在,如果不存在,马上断言失败退出逻辑

2.查看用户输入的密码是不是跟数据库中的数据是一样的,如果不是马上断言退出

3.查看用户状态是不是正常。如果不正常马上断言退出

4.记录登录日志

5.生产token



相关文章
|
8月前
|
Java Maven Android开发
微服务——SpringBoot使用归纳——Spring Boot开发环境搭建和项目启动
本文介绍了Spring Boot开发环境的搭建和项目启动流程。主要内容包括:jdk的配置(IDEA、STS/eclipse设置方法)、Spring Boot工程的构建方式(IDEA快速构建、官方构建工具start.spring.io使用)、maven配置(本地maven路径与阿里云镜像设置)以及编码配置(IDEA和eclipse中的编码设置)。通过这些步骤,帮助开发者顺利完成Spring Boot项目的初始化和运行准备。
730 0
微服务——SpringBoot使用归纳——Spring Boot开发环境搭建和项目启动
|
8月前
|
Java 测试技术 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
本课主要讲解Spring Boot项目中的属性配置方法。在实际开发中,测试与生产环境的配置往往不同,因此不应将配置信息硬编码在代码中,而应使用配置文件管理,如`application.yml`。例如,在微服务架构下,可通过配置文件设置调用其他服务的地址(如订单服务端口8002),并利用`@Value`注解在代码中读取这些配置值。这种方式使项目更灵活,便于后续修改和维护。
151 0
|
8月前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录——使用Logger在项目中打印日志
本文介绍了如何在项目中使用Logger打印日志。通过SLF4J和Logback,可设置不同日志级别(如DEBUG、INFO、WARN、ERROR)并支持占位符输出动态信息。示例代码展示了日志在控制器中的应用,说明了日志配置对问题排查的重要性。附课程源码下载链接供实践参考。
1006 0
|
8月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
461 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
6月前
|
Java 关系型数据库 MySQL
在Linux平台上进行JDK、Tomcat、MySQL的安装并部署后端项目
现在,你可以通过访问http://Your_IP:Tomcat_Port/Your_Project访问你的项目了。如果一切顺利,你将看到那绚烂的胜利之光照耀在你的项目之上!
386 41
|
11月前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
7月前
|
人工智能 小程序 NoSQL
【一步步开发AI运动小程序】二十一、如何将AI运动项目配置持久化到后端?
本文介绍基于云智「Ai运动识别引擎」的运动配置持久化方案,旨在优化小程序或Uni APP中AI运动识别能力。通过将运动检测参数(如`Key`、`Name`、`TickMode`、`rules`或`samples`)持久化到后端,可避免因频繁调整运动参数而重新发布应用,提升用户体验。持久化数据结构支持规则和姿态样本存储,适用于关系数据库、文件或文档数据库(如MongoDB)。此外,云智还提供运动自动适配工具及「AI乐运动」产品,助力快速实现AI体育、全民健身等场景。
|
9月前
|
SQL JavaScript 安全
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
416 11
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
|
8月前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
351 0
|
8月前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
在微服务架构中,随着业务复杂度增加,项目可能需要调用多个微服务。为避免使用`@Value`注解逐一引入配置的繁琐,可通过定义配置类(如`MicroServiceUrl`)并结合`@ConfigurationProperties`注解实现批量管理。此方法需在配置文件中设置微服务地址(如订单、用户、购物车服务),并通过`@Component`将配置类纳入Spring容器。最后,在Controller中通过`@Resource`注入配置类即可便捷使用,提升代码可维护性。
166 0

热门文章

最新文章