【项目实践】公寓租赁项目(十):基于SpringBoot登录管理接口开发

RT-DETR算法优化改进:轻量级上采样CARAFE算子 | 注意力机制大作战 上采样操作CARAFE,具有感受野大、内容感知、轻量级、计算速度快等优点,引入RT-DETR二次创新;1)代替Upsample进行使用; 阅读详情

目录

登录接口说明:LoginController

一、获取图形验证码接口

controller层:

service层:

二、登录接口

controller层:

service层:

mapper层:

三、JwtUtil创建

四、获取登陆用户个人信息接口

controller层:

(重要)因为我们解析token的方法是在拦截器里调用,所以如果我们每一次获取登录者的时候,要获取token进行解析,连续调用两次parseToken()方法就不太合理了。所以为避免重复解析,通常会在拦截器将Token解析完毕后,将结果保存至ThreadLocal中,这样一来,我们便可以在整个请求的处理流程中进行访问了。

修改拦截器:

service层:


登录接口说明:LoginController

@Tag(name = "后台管理系统登录管理")
@RestController
@RequestMapping("/admin")
public class LoginController {

    @Autowired
    private LoginService service;
}

一、获取图形验证码接口

接口名称:getCaptcha

请求方式:Get

请求路径:/admin/login/captcha

请求参数:无

返回类型:CaptchaVo

我们先查看CaptchaVo有哪些属性:

@Data
@Schema(description = "图像验证码")
@AllArgsConstructor
public class CaptchaVo {

    @Schema(description="验证码图片信息")
    private String image;

    @Schema(description="验证码key")
    private String key;
}

需要获取验证码图片的信息和存储在redis里的key。那么怎么生成验证码呢?我们需要使用开源的验证码生成工具EasyCaptcha。

导入maven依赖:

<dependency>
    <groupId>com.github.whvcse</groupId>
    <artifactId>easy-captcha</artifactId>
</dependency>

controller层:

@Operation(summary = "获取图形验证码")
    @GetMapping("login/captcha")
    public Result<CaptchaVo> getCaptcha() {
        CaptchaVo result= service.getCaptcha();
        return Result.ok(result);
    }

service层:

public CaptchaVo getCaptcha() {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);  //分别设置验证码区域的长、宽、以及验证码长度。
        String code = specCaptcha.text().toLowerCase();  //把验证码转成小写
        String key = RedisConstant.ADMIN_LOGIN_PREFIX + UUID.randomUUID(); //遵循命名规范

        stringRedisTemplate.opsForValue().set(key,code,RedisConstant.ADMIN_LOGIN_CAPTCHA_TTL_SEC, TimeUnit.SECONDS);  //把key和验证码值存入redis
        return new CaptchaVo(specCaptcha.toBase64(),key);
    }

本项目Reids中的key需遵循以下命名规范:项目名:功能模块名:其他,例如admin:login:123456


二、登录接口

接口名称:login

请求方式:Post

请求路径:/admin/login

请求参数:@RequestBody LoginVo loginVo

返回类型:Result<String>

controller层:

@Operation(summary = "登录")
    @PostMapping("login")
    public Result<String> login(@RequestBody LoginVo loginVo) {
        String jwt=service.login(loginVo);
        return Result.ok(jwt);
    }

loginVo用来封装前端登录界面用户提交的用户名、密码、验证码以及验证码在redis的key。

@Data
@Schema(description = "后台管理系统登录信息")
public class LoginVo {

    @Schema(description="用户名")
    private String username;

    @Schema(description="密码")
    private String password;

    @Schema(description="验证码key")
    private String captchaKey;

    @Schema(description="验证码code")
    private String captchaCode;
}

service层:

public String login(LoginVo loginVo) {
        if (loginVo.getCaptchaCode()==null){  //判断输入的验证码是否为空
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_NOT_FOUND);
        }

        String code = stringRedisTemplate.opsForValue().get(loginVo.getCaptchaKey());  //从redis中获取code
        if (code==null){  //判断查询的code是否为空
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_EXPIRED);
        }
        if (!code.equals(loginVo.getCaptchaCode().toLowerCase())){  //如果code与输入的code的小写相等
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_ERROR);
        }
        SystemUser systemUser = systemUserMapper.selectOneByUsername(loginVo.getUsername());  //通过用户名查询用户
        if (systemUser==null){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);
        }
        if (systemUser.getStatus()== BaseStatus.DISABLE){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);
        }
        if (!systemUser.getPassword().equals(DigestUtils.md5Hex(loginVo.getPassword()))){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);
        }
        return JwtUtil.createToken(systemUser.getId(),systemUser.getUsername());  //返回token
    }

mapper层:

自定义通过用户名字查询用户的方法。

 <select id="selectOneByUsername" resultType="com.atguigu.lease.model.entity.SystemUser">
        select id,
               username,
               password,
               name,
               type,
               phone,
               avatar_url,
               additional_info,
               post_id,
               status
        from system_user
        where is_deleted = 0
          and username = #{username}
    </select>

三、JwtUtil创建

JwtUtil是用来生成token来识别登录的用户是否合法,如果合法则从数据库中查询用户信息,并响应给前端。而且后续前端想要请求后端接口也需要解析携带的token。

导入依赖:

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

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <scope>runtime</scope>
</dependency>
public class JwtUtil {

    private static long tokenExpiration = 60 * 60 * 1000L;
    private static SecretKey tokenSignKey = Keys.hmacShaKeyFor("M0PKKI6pYGVWWfDZw90a0lTpGYX1d4AQ".getBytes());

    /**
     * 创建token方法
     * @param userId
     * @param username
     * @return
     */
    public static String createToken(Long userId, String username) {
        String token = Jwts.builder().
                setSubject("LOGIN_USER").
                setExpiration(new Date(System.currentTimeMillis() + 3600000)).
                claim("userId", userId).
                claim("username", username).
                signWith(tokenSignKey, SignatureAlgorithm.HS256).
                compact();
        return token;
    }

    /**
     * 解析token方法
     * @param token
     * @return
     */
    public static Claims parseToken(String token){
        if (token==null){
            throw new LeaseException(ResultCodeEnum.ADMIN_LOGIN_AUTH);
        }

        try {
            JwtParser jwtParser = Jwts.parser().setSigningKey(tokenSignKey)
                    .build();
            Jws<Claims> claimsJws = jwtParser.parseClaimsJws(token);
            Claims claims = claimsJws.getBody();
            return claims;
        }catch (ExpiredJwtException e){
            throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);
        }catch (JwtException e){
            throw new LeaseException(ResultCodeEnum.TOKEN_INVALID);
        }

    }

四、获取登陆用户个人信息接口

接口名称:info

请求方式:Get

请求路径:/admin/info

请求参数:无

返回类型:Result<SystemUserInfoVo>

controller层:

返回的类型为VO对象,需要自己定义查询方法。

(重要)因为我们解析token的方法是在拦截器里调用,所以如果我们每一次获取登录者的时候,要获取token进行解析,连续调用两次parseToken()方法就不太合理了。所以为避免重复解析,通常会在拦截器将Token解析完毕后,将结果保存至ThreadLocal中,这样一来,我们便可以在整个请求的处理流程中进行访问了。

ThreadLocal的主要作用是为每个使用它的线程提供一个独立的变量副本,使每个线程都可以操作自己的变量,而不会互相干扰,其用法如下图所示。

每个ThreadLocal对象都拥有set、get、remove方法,我们只需要编写逻辑调用即可自定义存储、获取、清理本地线程对象的方法。

public class LoginUserHolder {
    public static ThreadLocal<LoginUser> threadLocal = new ThreadLocal<>();  //创建本地线程对象

    public static void setLoginUser(LoginUser loginUser) {
        threadLocal.set(loginUser);   //把登录用户信息存储进本地线程对象
    }

    public static LoginUser getLoginUser() {
        return threadLocal.get();  //获取登录用户信息
    }

    public static void clear() {
        threadLocal.remove();  //清理存储的用户信息
    }
}
@Operation(summary = "获取登录用户个人信息")
    @GetMapping("info")
    public Result<SystemUserInfoVo> info() {
        Long userId = LoginUserHolder.getLoginUser().getUserId();
        SystemUserInfoVo systemUserInfoVo=service.getLoginUserInfoById(userId);
        return Result.ok(systemUserInfoVo);
    }

修改拦截器:

@Component
public class AuthenticationIntercepter implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("access-token");
        Claims claims = JwtUtil.parseToken(token);
        Long userId = claims.get("userId", Long.class);
        String username = claims.get("username", String.class);
        LoginUserHolder.setLoginUser(new LoginUser(userId, username));  //封装登录对象存储进本地线程对象
        return true;
    }



    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        LoginUserHolder.clear();  //清理本地线程方法
    }
}

service层:

public SystemUserInfoVo getLoginUserInfoById(Long userId) {
        SystemUser systemUser = systemUserMapper.selectById(userId);
        SystemUserInfoVo systemUserInfoVo = new SystemUserInfoVo();
        systemUserInfoVo.setAvatarUrl(systemUser.getAvatarUrl());
        systemUserInfoVo.setName(systemUser.getName());
        return systemUserInfoVo;
    }

【硬刚Hadoop】HADOOP MAPREDUCE(1):概述 本文是对《【硬刚大数据之学习路线篇】从零到大数据专家的学习指南(全面升级版)》的Hadoop部分补充。 1 MapReduce定义 MapReduce是一个分布式运算程序的编程框架,是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。 2MapReduce优缺点 2.1 优点 1)MapReduce易于编程 它简单的实现一些接口,就可以完成一个分布式程序.. 阅读详情

相关推荐

GROMACS自由能景观图绘制全流程:从PCA分析到Origin 3D可视化(附避坑指南)

本文详细解析了使用GROMACS绘制自由能景观图的全流程,涵盖从PCA分析、数据预处理、自由能计算到最终在Origin中进行3D可视化的完整步骤。文章重点分享了数据处理与格式转换中的常见“避坑”指南,帮助研究者从分子动力学轨迹中有效提取并解读构象自由能信息,深化对生物大分子动力学过程的理解。

oauth7security的博客 309

SpringBoot3 登录管理实现

一、背景知识1. 认证方案概述有两种常见的认证方案,分别是基于Session的认证和基于Token的认证,下面逐一进行介绍基于Session基于Session的认证流程如下图所示该方案的特点登录用户信息保存在服务端内存中,若访问量增加,单台节点压力会较大随用户规模增大,若后台升级为集群,则需要解决集群中各服务器登录状态共享...

weixin_41607646的博客 249

银河麒麟系统下VSCode安装全攻略:从下载到桌面快捷方式(附常见问题解决)

本文详细介绍了在银河麒麟系统下安装和优化VSCode的全流程,包括环境准备、安装策略、权限管理、桌面快捷方式创建以及系统级性能调优。特别针对国产系统环境提供了常见问题解决方案和必备插件推荐,帮助开发者高效配置开发环境。

v6b7n8m9q0的博客 1133

SpringBoot实战:登录管理

认证方案   基于Sessioon   基于ToKen ToKen详解 登录流程   验证码接口   登录接口 JWT

2301_79526467的博客 1523

电路课设-音响分频器电路设计

(一)题目简介 1.一阶分频器电路设计 假定高音和低音扬声器均等效为 16 欧姆电阻,设计如图 2 的简单分频器电 路,要求高低频分界(两个滤波器的截止频率)为 5kHz。 1) 写出高音扬声器和低音扬声器电压对于 vs 的传递函数,确定电路中电 容 C 和电感 L 的元件值;2)利用 AC 频率扫描分析求出两个扬声器电压的频率响应曲线,验证计算 结果。用包含高低频成分的电压 vs 激励进行测量验证。 3)计算并利用 EWB 仿真证明从 vs 看进去的阻抗为一常数 16 欧姆。

weixin_53507617的博客 1万+

自动驾驶控制算法——MPC控制算法

自动驾驶MPC控制算法摘要 模型预测控制(MPC)是一种基于系统预测模型的先进控制算法,通过滚动优化方式求解最优控制输入。其核心流程包括:1)使用数学模型预测未来系统状态;2)定义优化目标函数衡量预测误差;3)求解满足约束的最优控制序列;4)仅执行第一步控制并重复该过程。 相比传统PID控制,MPC具有预测未来、多步优化、显式处理约束等优势,特别适合自动驾驶中对安全性要求高的场景,如轨迹跟踪、车道保持、联合纵横向控制、自动泊车和动态避障等。MPC通过状态空间模型预测系统行为,在每个控制周期计算未来N步的控制

swaggytiger的博客 7919

【项目实践】公寓租赁项目(十一):基于SpringBoot开发移动端登录管理接口

本文介绍了基于Spring Boot和阿里云短信服务实现的登录系统接口开发。系统包含三个主要接口:1) 获取短信验证码接口,通过阿里云短信服务发送验证码并存入Redis;2) 登录接口,验证短信验证码并返回JWT令牌,支持自动注册新用户;3) 获取用户信息接口,通过JWT解析用户身份后返回用户基本信息。系统采用Redis存储验证码并实现防刷机制,验证码有效期为300秒,60秒内不允许重复获取。开发过程中需要配置阿里云短信服务的AccessKey和模板参数,并集成Redis作为缓存服务。该系统实现了完整的短信

BeingACoder的博客 1037

ks-快手滑块验证码-Js逆向

本文分析了快手滑块验证码的破解过程。首先通过抓包找到验证码背景图接口,发现需要动态获取captchaSession参数。然后深入分析验证流程,发现verifyParam参数被加密处理,需要追踪其生成逻辑。文章详细解析了加密参数c的构成,包括captchaSn、滑动距离、轨迹信息等,并指出轨迹验证较为严格。最后通过对比浏览器和本地生成的加密值,确认加密逻辑正确,但指出轨迹生成仍需优化。作者建议参考相关文章深入分析轨迹逻辑,并提供了验证成功的截图作为参考。

2302_76420666的博客 1875

springboot公寓租赁系统-计算机毕业设计源码03822

摘要 在当前全球化和城市化进程中,公寓租赁市场正经历着前所未有的发展。然而,随着市场规模的扩大,公寓租赁系统也面临着诸多挑战,如信息不对称、租赁流程繁琐、租金支付不便等问题。这些问题不仅影响了租户的租房体验,也给公寓运营商带来了管理上的困扰。因此,如何构建一个高效、便捷、透明的公寓租赁系统,成为了亟待解决的问题。 本文以公寓租赁系统为研究对象,运用了系统分析和设计的方法,从用户需求分析、功能模块设计、系统架构设计等方面进行了全面的研究和探讨。

vxbishe2的博客 1421

从零构建:毫米波雷达生命信号检测系统的Matlab仿真全流程解析

本文详细解析了毫米波雷达生命信号检测系统的Matlab仿真全流程,涵盖原理、信号处理链路设计及算法优化策略。通过FMCW雷达技术,实现非接触式呼吸心跳信号检测,结合Matlab代码示例展示距离FFT、相位提取与信号分离等关键步骤,为医疗监护和智能家居应用提供实用指南。

weixin_29303701的博客 354

Linux 下安装 openjdk 17【详细步骤】

JDK17,安装教程。

甘蓝的专栏 7501

基于springboot的公寓租赁管理系统

基于springboot的公寓租赁管理系统

【可全包】本人程序员,不需要做任何吹嘘,只是实在写点程序,写点文档,熟悉各类主流框架,SSM,SpringBoot,Flask,Djiango,Mysql,Sqlite,VUE,Uniapp等,各类程序设计专家,优质作者 1185

【全局路径规划地图算法】Voronoi路径规划探索(附C++代码)

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对Voronoi路径规划探索做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容。

qq_35635374的博客 2239

springboot公寓租赁管理系统--附源码00161

随着城市化进程的加快,公寓租赁市场需求日益增长,对高效管理工具的需求也愈发明显。在这样的背景下,“Spring Boot公寓租赁管理系统”应运而生,基于Java语言开发,利用其跨平台特性和强大的生态系统,构建了一个高效、稳定的在线租赁管理平台。系统采用Spring Boot框架,简化了后端开发流程,结合MySQL数据库实现数据存储与管理,设计支持前后端分离,提升了系统的灵活性和响应速度。该系统为房东提供了从房源信息发布到租赁合同管理等一系列功能,包括处理看房预约和退租请求等...............

weixin_BYSJ1987的博客 903

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

尚庭公寓管理系统项目面试

header:头部,通常包含算法类型(如HS256)payload:载荷,包含用户信息及声明(claims)signature:签名,用于校验数据完整性一致:说明token没有被篡改,签名合法不一致:token被篡改,校验失败,拒绝访问JWT校验的关键在于用服务端的密钥对header和payload重新签名,和传入的签名比较只要密钥不泄露,且签名匹配,证明数据完整且可信JWT本身不存储状态,校验只依赖签名和声明登录之后获取用户信息。

m0_62925761的博客 2367

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

基于springboot公寓租赁系统-计算机毕设 附源码 58929

租客注册:点击注册,进入注册页面,填写好账号、密码、确认密码、昵称、邮箱、身份:租客、用户姓名、用户性别、用户电话等字段值,点击下方注册按钮,提示注册成功后,系统将自动跳转回到登录页面。 (2)用户登录:点击“登录”按钮,输入用户名、密码、验证码登录系统,登录时前端会自动校验用户名与密码以及该用户是否审核通过,审核通过的用户输入正确登录成功,输入错误会有提示信息。 (3)首页:展示轮播图、租房资讯、房源信息推荐。 (4)系统公告:展示后台发布的所有系统系统公告,点击详情可查看具体公告详情信息。 (5)

WeiXin_DZbishe的博客 1690

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

基于SpringBoot的公寓租赁管理系统

前端页面数据处理传输以及页面展示使用Vue技术 采用B/S架构,使用Maven作为项目管理工具,使用Springboot+Mybatis做整合开发 ,基于SpringBoot的公寓租赁管理系统采用的开发工具:IntelliJ IDEA,VScode;数据库管理软件:Navicat;开发技术框架:MyBatis,Spring Boot,Vue;使用Mysql数据库构建数据库表开发步骤;(1) 创建好数据库并导入,

QQ402205496的博客 766

基于SpringBoot的公寓出租系统

基于SpringBoot的公寓出租系统是一个集成了现代信息技术的高效租赁管理平台,旨在满足房东、租客和管理员等不同用户角色的需求。

q_q1262330535的博客 992

springboot公寓租赁系统-计算机设计毕业源码03822

公寓租赁系统的研究也致力于提升租赁服务质量。通过系统化的租户管理和维修请求处理,房东或租赁机构能够更好地满足租户的需求,提供高质量的租赁服务。同时,利用大数据分析技术对租赁市场进行数据分析,有助于房东或租赁机构做出科学决策,优化经营策略和资源配置。

weixin_MZ_ZXD001的博客 807

基于SpringBoot的公寓出租系统的设计与实现

未来,随着技术的不断进步和用户需求的变化,我们可以进一步完善系统功能,如增加在线支付、房源评价等模块,同时优化用户体验,提高系统的稳定性和安全性。因此,设计和实现一个基于SpringBoot的公寓出租系统,对于提高公寓出租管理的效率和质量具有重要意义。SpringBoot简化了Spring应用的创建和开发过程,提供了丰富的内置功能和自动配置选项,降低了开发难度和成本。MySQL是一种广泛使用的开源关系型数据库管理系统,具有高性能、可靠性和易用性等优点,能够满足公寓出租系统的数据存储需求。

QQ346127357的博客 697

springboot公寓租赁管理系统-毕业设计源码50248

随着城市化进程的加速和人口流动性的增加,房屋租赁市场逐渐成为人们生活的重要组成部分。在这个市场中,房屋租赁管理系统扮演着至关重要的角色。本系统采取MySQL作为后台数据的主要存储单元,采用SpringBoot框架、Java语言进行业务系统的编码及其开发,实现了本系统的全部功能。系统主要包括租客用户、房东用户和管理员用户功能三大模块。 本文首先分析了课题的研究的背景和意义,针对房屋租赁管理系统的各项需求及开发的可行性进行分析;然后对设计系统需要使用的技术软件以及设计思想做了基本的介绍.............

weixin_BYSJ1987的博客 1742
上一篇: 【项目实践】公寓租赁项目(九):SpringBoot与Redis整合的快速入门使用
下一篇: 【项目实践】公寓租赁项目(十一):基于SpringBoot开发移动端登录管理接口
BeingACoder
博客等级 码龄1年 106粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值