SpringBootWeb 登录认证

登录认证,那什么是认证呢?

  • 所谓认证指的就是根据用户名和密码校验用户身份的这个过程,认证成功之后,我们才可以访问系统当中的信息,否则就拒绝访问。

在前面的案例中,我们已经实现了部门管理、员工管理的基本功能,但是大家会发现,我们并没有登录,就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的,所以我们今天的主题就是登录认证最终我们要实现的效果就是用户必须登录之后,才可以访问后台系统中的功能

  • 在登录页面中,用户要输入用户名,输入密码,然后接下来点击登录,如果输入的用户名或者密码错误,此时就会停留在登录页面当中,并且提示出对应的错误信息;
  • 如果用户名和密码都是正确的,我们点击登录按钮,此时才会进入到系统当中,进入到系统之后,我们就可以来操作系统当中的数据了。

要想实现用户登录的功能,我们需要两步操作来实现:

  1. 首先第一步,我们要先来完成最为基础的登录功能,这步操作就是来判断用户输入的用户名和密码是否正确
  2. 第二步,我们要来完成登录校验操作:登录校验指的就是当我们浏览器发起一个请求之后,服务端需要判断这个用户是否登录了,如果登录了,则执行正常的业务操作;如果没有登录,就需要跳转到登录界面,让他完成登录之后再来访问这个系统。 

注意:登录校验是整个登录功能的核心! 

1. 登录功能

1.1 需求

在登录界面中,我们可以输入用户的用户名以及密码,然后点击 "登录" 按钮就要请求服务器,服务端判断用户输入的用户名或者密码是否正确。如果正确,则返回成功结果,前端跳转至系统首页面。 

思考:在登录的时候,我们需要校验用户名和密码是否正确,这条SQL语句该怎么写?

回答:其实非常简单,逆向思考就是根据用户名和密码来查询员工,如果根据用户名和密码,我查询到了员工,就说明用户名和密码是正确的;如果根据用户名和密码,我没有查询到员工,就说明用户名或密码错误。

SQL语句:

-- 登录时校验用户名和密码
select * from emp where username = '' and password = '';

思考:根据这条SQL语句查询出来的员工有没有可能是多个?

回答:不可能,因为之前我们创建emp员工表的时候,针对于username这个字段我们添加的是unique唯一约束,所以username这个它是不可能重复的,因此最终我们查询出来的数据,最多只会有一条。

1.2 接口文档

  • 我们参照接口文档来开发登录功能

基本信息

  • 请求参数

参数格式:application/json

参数说明:

名称类型是否必须备注
usernamestring必须用户名
passwordstring必须密码

请求数据样例:

 

  • 响应数据

参数格式:application/json

参数说明:

名称类型是否必须默认值备注其他信息
codenumber必须响应码, 1 成功 ; 0 失败
msgstring非必须提示信息
datastring必须返回的数据 , jwt令牌

响应数据样例:  

1.3 登录 - 思路分析

说明:目前我们先不考虑返回JWT令牌,目前我们只是给前端响应成功还是失败。

首先第一件事,我们肯定需要在Controller当中定义一个方法来处理这个登录请求此时需要思考登录这个请求方法我们应该定义哪一个Controller当中?
是DeptController,还是EmpController,还是UploadController,都不是,原因:DeptController的请求路径是/depts,EmpController的请求路径是/emps,UploadController的请求路径是/upload,并且UploadController是用来进行文件上传的。 

因此,我们需要再定义一个Controller,专门用来处理登录请求,取名叫LoginController,然后我们在LoginController当中再来定义一个方法来处理登录的请求,由于登录的请求方式是一个POST请求,所以我们需要在该方法上面加上@PostMapping,而且请求格式的参数是一个JSON格式的请求参数,最终服务端要把JSON格式的参数封装到一个对象当中,所以我们要在方法的形参上加上@RequestBody注解来接收前端传递过来的JSON格式的数据并填充到实体类中,

登录服务端的核心逻辑就是:接收前端请求传递的用户名和密码 ,然后再根据用户名和密码查询用户信息,如果用户信息存在,则说明用户输入的用户名和密码正确。如果查询到的用户不存在,则说明用户输入的用户名和密码错误。  

1.4 功能开发

LoginController

package com.gch.controller;import com.gch.pojo.Emp;
import com.gch.pojo.Result;
import com.gch.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@RequestMapping("/login")
/**登录功能控制器*/
public class LoginController {@Autowiredprivate EmpService empService;/*** 处理登录请求* @param emp 员工对象* @return 响应*/@PostMappingpublic Result login(@RequestBody Emp emp) {// 1.记录日志log.info("处理该用户登录请求,username:{}, password:{}", emp.getUsername(), emp.getPassword());// 2.调用service进行查询,查询/校验该用户信息是否存在Emp e = empService.login(emp);// 3.响应return e != null ? Result.success(e) : Result.error("用户名或密码错误");}
}

EmpService

package com.gch.service;import com.gch.pojo.Emp;
import com.gch.pojo.PageBean;import java.time.LocalDate;
import java.util.List;/**员工业务规则*/
public interface EmpService {/*** 处理该用户的登录请求* @param emp 员工对象* @return 根据前端传递的用户信息返回查询到的员工对象*/Emp login(Emp emp);
}

EmpServiceImpl

package com.gch.service.impl;import com.gch.mapper.EmpMapper;
import com.gch.pojo.Emp;
import com.gch.pojo.PageBean;
import com.gch.service.EmpService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;/**员工业务实现类*/
@Slf4j
@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;/*** 处理该用户的登录请求* @param emp 员工对象* @return 根据前端传递的用户信息返回查询到的员工对象*/@Overridepublic Emp login(Emp emp) {// 1.调用Mapper层查询该员工信息Emp loginEmp = empMapper.getByUsernameAndPassword(emp);// 2.返回查询结果给Controllerreturn loginEmp;}
}

EmpMapper

package com.gch.mapper;import com.gch.pojo.Emp;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;import java.time.LocalDate;
import java.util.List;/**员工管理*/
@Mapper
public interface EmpMapper {/*** 处理该用户的登录请求* 根据用户名和密码查询员工* @param emp 员工对象* @return 根据前端传递过来的请求参数中的用户信息查询员工是否存在*/@Select("select * from tlias.emp where username = #{username} and password = #{password}")Emp getByUsernameAndPassword(Emp emp);
}

1.5 测试

功能开发完毕后,我们就可以启动服务,打开Postman进行测试了。

发起POST请求,访问:http://localhost:8080/login

Postman测试通过了,那接下来,我们就可以结合着前端工程进行联调测试

先退出系统,进入到登录页面:  

在登录页面输入账户密码:  

故意把密码输错,看登陆页面会不会提示错误!

注意:提示错误的信息,就是在Controller中响应给前端的信息!

 

登录成功之后进入到后台管理系统页面:  

2. 登录校验

2.1 问题分析

我们已经完成了基础登录功能的开发与测试,并且完成了前后端联调,在我们登录成功后就可以进入到后台管理系统中进行数据的操作。  

但是当我们在浏览器中新的页面上输入地址:http://localhost:9528/#/system/dept也就是复制了已经登录进入后台管理系统的页面地址,接着退出后台管理系统,然后关闭该页面,再次打开一个新的标签页,然后粘贴进入刚才已经登录进入后台管理系统的页面地址,发现没有登录仍然可以进入到后端管理系统页面。

而真正的登录功能应该是:登陆后才能访问后端系统页面,不登陆则跳转登陆页面进行登陆。 

这是异常现象!

问题:在未登录情况下,我们也可以直接访问部门管理、员工管理等功能。

为什么会出现这个问题?

  • 其实原因很简单,就是因为针对于我们当前所开发的部门管理、员工管理以及文件上传等相关接口来说,我们在服务器端并没有做任何的判断,没有去判断用户是否登录了。所以无论用户是否登录,都可以访问部门管理以及员工管理的相关数据。所以我们目前所开发的登录功能,它只是徒有其表。而我们要想解决这个问题,我们就需要完成一步非常重要的操作:登录校验。

什么是登录校验?

  • 所谓登录校验,指的是我们在服务器端接收到浏览器发送过来的请求之后,首先我们要对请求进行校验。先要校验一下用户登录了没有,如果用户已经登录了,就直接执行对应的业务操作就可以了;如果用户没有登录,此时就不允许他执行相关的业务操作,直接给前端响应一个错误的结果,最终跳转到登录页面,要求他登录成功之后,再来访问对应的数据。

了解完什么是登录校验之后,接下来我们分析一下登录校验大概的实现思路。  

首先我们在宏观上先有一个认知,然后再来逐个击破:

前面在讲解HTTP协议的时候,我们提到HTTP协议是无状态协议什么又是无状态的协议?

  • 所谓无状态指的是每一次请求都是独立的,下一次请求并不会携带上一次请求的数据。而浏览器与服务器之间进行交互,是基于HTTP协议的,也就意味着现在我们通过浏览器来访问了登陆这个接口,实现了登陆的操作,接下来我们在执行其他业务操作时,服务器也并不知道这个员工到底登陆了没有。因为HTTP协议是无状态的,两次请求之间是独立的,所以是无法判断这个员工到底登陆了没有。

那应该怎么来实现登录校验的操作呢?具体的实现思路可以分为两部分:  

  1. 在服务端要想判断这个员工是否已经登录,我们就需要在员工登录成功之后,要存储这么一个登录成功的标记,一旦员工登陆成功,那我们就存储登录成功的这样一个标记,记录用户已经登录成功的标记;
  2. 然后接下来我们在每一个接口方法执行之前,先来做一个条件判断,来判断一下这个员工到底登录了没有,如果这个员工已经登录了,那接下来,我们就执行正常的业务操作就可以了;如果这个员工没有登录,我们在这一块儿直接返回错误的信息,把这个错误的信息返回给前端,前端拿到这个错误的信息之后,它会自动的跳转到登陆页面。

我们程序中所开发的查询功能、删除功能、添加功能、修改功能,都需要使用以上套路进行登录校验。此时就会出现:相同代码逻辑,每个功能都需要编写,就会造成代码非常繁琐。

为了简化这块操作,我们可以使用一种技术:统一拦截技术。

  • 通过统一拦截的技术,我们可以来拦截浏览器发送过来的所有的请求,拦截到这个请求之后,就可以通过请求来获取之前所存入的登录标记,在获取到登录标记,且标记为登录成功,就说明员工已经登录了。如果已经登录,我们就直接放行(意思就是可以访问正常的业务接口了)。
  1. 在员工登录成功后,需要将用户登录成功的信息存起来,记录用户已经登录成功的标记。

  2. 在浏览器发起请求时,需要在服务端进行统一拦截,拦截后进行登录校验。

统一拦截技术

   

我们要完成以上登录校验的操作,会涉及到Web开发中的两个技术:

  1. 会话技术

  2. 统一拦截技术

    

 

 

异常处理的方案!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/53041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch建立MyDataLoader过程详解

简介 torch.utils.data.DataLoader(dataset, batch_size1, shuffleNone, samplerNone, batch_samplerNone, num_workers0, collate_fnNone, pin_memoryFalse, drop_lastFalse, timeout0, worker_init_fnNone, multiprocessing_contextNone, generatorNone, *, prefetch_factorN…

【2023钉钉杯复赛】A题 智能手机用户监测数据分析 Python代码分析

【2023钉钉杯复赛】A题 智能手机用户监测数据分析 Python代码分析 1 题目 一、问题背景 近年来,随着智能手机的产生,发展到爆炸式的普及增长,不仅推动了中 国智能手机市场的发展和扩大,还快速的促进手机软件的开发。近年中国智能…

CleanMyMac2024永久版Mac清理工具

Mac电脑作为相对封闭的一个系统,它会中毒吗?如果有一天Mac电脑产生了疑似中毒或者遭到恶意不知名攻击的现象,那又应该如何从容应对呢?这些问题都是小编使用Mac系统一段时间后产生的疑惑,通过一番搜索研究,小…

Redis 7 教程 数据类型 基础篇

🌹 引导 Commands | Redishttps://redis.io/commands/Redis命令中心(Redis commands) -- Redis中国用户组(CRUG)Redis命令大全,显示全部已知的redis命令,redis集群相关命令,近期也会翻译过来,Redis命令参考,也可以直接输入命令进行命令检索。

10 - 网络通信优化之通信协议:如何优化RPC网络通信?

微服务框架中 SpringCloud 和 Dubbo 的使用最为广泛,行业内也一直存在着对两者的比较,很多技术人会为这两个框架哪个更好而争辩。 我记得我们部门在搭建微服务框架时,也在技术选型上纠结良久,还曾一度有过激烈的讨论。当前 Sprin…

OSCS开源安全周报第 56 期:Apache Airflow Spark Provider 任意文件读取漏洞

本周安全态势综述 OSCS 社区共收录安全漏洞 3 个,公开漏洞值得关注的是 Apache NiFi 连接 URL 验证绕过漏洞(CVE-2023-40037)、PowerJob 未授权访问漏洞(CVE-2023-36106)、Apache Airflow Spark Provider 任意文件读取漏洞(CVE-2023-40272)。 针对 NPM 、PyPI 仓库…

开发一款AR导览导航小程序多少钱?ar地图微信小程序 ar导航 源码

随着科技的不断发展,增强现实(AR)技术在不同领域展现出了巨大的潜力。AR导览小程序作为其中的一种应用形式,为用户提供了全新的观赏和学习体验。然而,开发一款高质量的AR导览小程序需要投入大量的时间、人力和技术资源…

记录一次presto sql执行报错 Error executing query的解决办法

在执行presto sql 时报错截图如下: 查看后台执行报错日志: java.sql.SQLException: Error executing query at com.facebook.presto.jdbc.PrestoStatement.internalExecute(PrestoStatement.java:307) at com.facebook.presto.jdbc.PrestoStatement.exe…

elment-ui中使用el-steps案例

el-steps案例 样式 代码 <div class"active-box"><div class"active-title">请完善</div><el-steps :active"active" finish-status"success" align-center><el-step title"第一步" /><…

Qt ui对某控件进行全局提升报错:no such file or directory

问题 在Qt项目中&#xff0c;设计师界面&#xff0c;对某一控件进行提升&#xff0c;设置完“提升的类名称”、“头文件”、全局包含后&#xff0c;构建时&#xff0c;报“no such file or directory”错误&#xff0c;但文件命名存在呀。 解决 根据问题就应该明白&#xf…

MAE 论文精读 | 在CV领域自监督的Bert思想

1. 背景 之前我们了解了VIT和transformer MAE 是基于VIT的&#xff0c;不过像BERT探索了自监督学习在NLP领域的transformer架构的应用&#xff0c;MAE探索了自监督学习在CV的transformer的应用 论文标题中的Auto就是说标号来自于图片本身&#xff0c;暗示了这种无监督的学习 …

html实现页面切换、顶部标签栏(可删、可切换,点击左侧超链接出现标签栏)

一、在一个页面&#xff08;不跨页面&#xff09; 效果&#xff1a; 代码 <!DOCTYPE html> <html><head><style>/* 设置标签页外层容器样式 */.tab-container {width: 100%;background-color: #f1f1f1;overflow: hidden;}/* 设置标签页选项卡的样式…

lnmp架构-PHP

08 PHP源码编译 09 php初始化配置 nginx 的并发能力强 phpinfo函数 就是 显示php信息 10 php的功能模块 编译memcache模块 php的动态模块方式 mamcache 就是内存 直接从内存中命中 所以性能非常好 但是 这还不是最好的方式 工作流程 关键看后端的 php 什么时候处理完 mamcac…

WPF读取dicom序列:实现上一帧、下一帧、自动播放、暂停

一、整体设计概况 创建WPF程序使用.Net Framework4.8定义Image控件展示图像增加标签展示dcm文件信息规划按钮触发对应的事件:上一帧、下一帧、自动播放、暂停、缩放、播放速率二、页面展示 三、代码逻辑分析 Windows窗体加载Loaded事件:生成初始图像信息Windows窗体加载Mous…

【Docker】Docker网络与存储(三)

前言&#xff1a; Docker网络与存储的作用是实现容器之间的通信和数据持久化&#xff0c;以便有效地部署、扩展和管理容器化应用程序。 文章目录 Docker网络桥接网络容器之间的通信 覆盖网络创建一个覆盖网络 Docker存储卷 总结 Docker网络 Docker网络是在容器之间提供通信的机…

Android中的APK打包与安全

aapt2命令行实现apk打包 apk文件结构 classes.dex&#xff1a;Dex&#xff0c;即Android Dalvik执行文件 AndroidManifest.xml&#xff1a;工程中AndroidManifest.xml编译后得到的二进制xml文件 META-INF&#xff1a;主要保存各个资源文件的SHA1 hash值&#xff0c;用于校验…

SMC_TRAFO_GantryCutter2 (FB) 带刀片旋向龙门

裁布机&#xff1a;刀片按XY走向&#xff0c;偏转刀片角度。 pi&#xff1a;目标位置矢量&#xff08;x&#xff0c;y&#xff09;&#xff0c;插值器的输出 v&#xff1a;当前路径切线的矢量&#xff0c;插值器的输出 dOffsetX&#xff1a; x轴的附加偏移 dOffsetY&#xf…

桥梁安全监测方法和内容是什么?

桥梁安全监测方法和内容是什么?桥梁监测是保障桥梁安全和稳定的重要手段。随着科技的进步&#xff0c;桥梁监测技术和设备不断完善&#xff0c;监测内容也越来越全面。本文万宾科技小编将为大家介绍桥梁安全监测的方法和内容&#xff0c;以期帮助大家更好地了解这一领域。 桥梁…

kafka--技术文档--spring-boot集成基础简单使用

阿丹&#xff1a; 查阅了很多资料了解到&#xff0c;使用了spring-boot中整合的kafka的使用是被封装好的。也就是说这些使用其实和在linux中的使用kafka代码的使用其实没有太大关系。但是逻辑是一样的。这点要注意&#xff01; 使用spring-boot整合kafka 1、导入依赖 核心配…

华为质量管理:从产品质量到用户体验,Kano模型成为新方向

目录 前言 华为质量管理的四个阶段 基于 IPD 如何做质量管理呢&#xff1f; CSDN相关课程 作者简介 前言 今天继续来谈谈华为流程体系中的质量管理过程。 通常来说质量具体是指产品的质量&#xff0c;也就是产品的使用价值及其属性。 产品再细分的话可以分为三个层次&a…