管理系统用户登录功能

news2024/10/7 14:29:51

一、前言

任何一个管理信息系统都会有登录功能。我们简单可以通过用户名加密码加验证码进行登录。但是就是一个这样的简单功能却涉及的要求很多。

比如对账号的要求,对密码复杂度的要求,对登录时长的要求,对密码有效期的要求,对登录用户登录日志的记录,登录用户的权限等等。非常非常多。本文就介绍简单的登录功能。

二、登录功能数据库表设计


-- Drop table

-- DROP TABLE public.t_user;

CREATE TABLE public.t_user (
	id varchar(32) NOT NULL,
	user_name varchar(255) NOT NULL,
	login_name varchar(255) NOT NULL,
	"password" varchar(255) NOT NULL,
	create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
	last_login_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
	deleted int4 NOT NULL DEFAULT 0,
	pwd_val_time timestamp NOT NULL,
	belong_code varchar(8) NULL,
	belong_name varchar(255) NULL,
	data_type varchar(255) NULL,
	phone varchar(255) NULL,
	CONSTRAINT t_user_pkey PRIMARY KEY (id)
);

 三、注册用户

注册用户分以下几步

1、判断新增的用户是否存在,如果存在不允许注册同账号的用户

2、判断用户名和密码是否是空

3、校验密码复杂度是否复合要求

4、对密码进行加密处理

5、报错新注册管理员账号

/**
	 * 保存后台管理用户信息
	 * @param tUser
	 * @return
	 */
	@ApiOperation(value = "保存后台管理用户信息", notes = "保存后台管理用户信息")
	@PostMapping("save")
	public ResponseData<Boolean> save(@RequestBody TUser tUser) {
		//先校验用户是否存在
		if(tUserService.userIsExists(tUser)) {
			log.error(TUserConstant.SAVE_USER_EXISTS);
			return ResponseData.error(TUserConstant.SAVE_USER_EXISTS);
		}

		if(StringUtils.isEmpty(tUser.getPassword()) || StringUtils.isEmpty(tUser.getLoginName())) {
			log.error(TUserConstant.SAVE_USER_EMP);
			return ResponseData.error(TUserConstant.SAVE_USER_EMP);
		}

		//校验密码复杂度
		Boolean checkPWD = tUserService.checkPWD(tUser.getPassword());
		if (!checkPWD) {
			log.error(TUserConstant.PWD_CHECK_ERROR);
			return ResponseData.error(TUserConstant.PWD_CHECK_ERROR);
		}
		
		tUser.setPassword(Des3Utils.get3DESEncryptECB(tUser.getPassword(), AES_KEY));
		tUser.setPwdValTime(new Date());
		boolean res = tUserService.save(tUser);
		if(res) {
			return ResponseData.success(true);
		}else {
			log.error(TUserConstant.SAVE_USER_ERROR);
			return ResponseData.error(TUserConstant.SAVE_USER_ERROR);
		}
	}

密码复杂度函数:

/**
	 * 校验复杂度
	 */
	public Boolean checkPWD(String PWD) {

		// 规定的正则表达式
		// (?![a-zA-Z]+$) 表示 字符串不能完全由大小写字母组成
		// (?![A-Z0-9]+$) 表示 字符串不能完全由大写字母和数字组成
		// (?![A-Z\W_]+$) 表示 字符串不能完全由大写字母和特殊字符组成
		// (?![a-z0-9]+$) 表示 字符串不能完全由小写字母和数字组成
		// (?![a-z\W_]+$) 表示 字符串不能完全由小写字母和特殊字符组成
		// (?![0-9\W_]+$) 表示 字符串不能完全由数字和特殊字符组成
		// [a-zA-Z0-9\W_]{8,} 表示 字符串应该匹配大小写字母、数字和特殊字符,至少匹配8次
		String regex = "^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![a-z0-9]+$)(?![A-Z\\W_]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,}$";

		return ReUtil.isMatch(regex, PWD);
	}

四、用户登录

1、限制频繁刷登录操作

2、校验码校验

3、校验用户和密码是否正确

4、判断密码是否过期是否需要重置密码

5、将登录信息写到缓存,设置不操作2小时过期

6、获取登录用户的权限

代码示例:

/**
	 * 后台管理用户登录
	 * @param tUser
	 * @return
	 */
	@ApiOperation(value = "后台管理用户登录", notes = "后台管理用户登录")
	@PostMapping("login")
	public ResponseData<String> login(@RequestBody Map<String,Object> map,HttpServletRequest request,HttpServletResponse response) {
		//防刷登录限制,一分钟内刷连续30次,限制访问
		if (!tUserService.isLimit(request,30)) {
			ResponseData<Object> responseData = ResponseData.error(ResponseCode.IS_LIMIT_ACC.getCode(),
					ResponseCode.IS_LIMIT_ACC.getMessage());
			tUserService.resNoPermiss(response, responseData);
			return ResponseData.error(TUserConstant.IS_LIMIT_ACC);
		}
		
		String verCode = "";
	  
		if(map.containsKey("verCode")) {
			verCode = map.get("verCode").toString();
		}else {
			return ResponseData.error(TUserConstant.VERCODE_EMP);
		} 
		
		 log.info("前端传入验证码:"+verCode);
		/**登录验证码(暂时屏蔽)**/
		if (!CaptchaUtil.ver(verCode, request)) {
			 log.info("验证码验证失败");
	         return ResponseData.error(TUserConstant.VERCODE_ERROE);
	     }
		
		TUser tUser = new TUser();
		if(map.containsKey("loginName")) {
			tUser.setLoginName(map.get("loginName").toString());
		} 
		if(map.containsKey("password")) {
			tUser.setPassword(map.get("password").toString()); 
		} 
		
		String pwdError = redisUtils.get(RedisKeys.getLoginPwdError(tUser.getLoginName()));
		if(!StringUtils.isEmpty(pwdError)) {
			if(Integer.parseInt(pwdError) > 4) {
				return ResponseData.error(TUserConstant.LOGIN_PERMISS_ERROR);	
			}
		}
		
		log.info("获取到后台登录的密码为:"+ tUser.getPassword());
		log.info("获取到后台登录的加密后的密码为:"+ Des3Utils.get3DESEncryptECB(tUser.getPassword(),AES_KEY));
		tUser.setPassword(Des3Utils.get3DESEncryptECB(tUser.getPassword(),AES_KEY));
		TUser tUserRes = tUserService.getByLoginName(tUser);
		if(null != tUserRes) {
			//判断密码更新时间是否超过有效期
			if (((new Date().getTime() - tUserRes.getPwdValTime().getTime())/(1000*3600*24)) > pwdValTime) {
				return ResponseData.error(-1,TUserConstant.PWD_VAL_TIME_ERROR);
			}
			//更新最后登录时间
			tUserService.updateUserLastLoginTime(tUser.getLoginName(), DateTimeUtils.getDateStr());
 
			// 添加session
			HttpSession session = request.getSession();
			try {
				session.setAttribute(Constant.CTG_ADMIN_USER_NAME,AesUtil.aesEncrypt(tUserRes.getUserName(),AES_KEY));
				session.setAttribute(Constant.CTG_ADMIN_USER_ID,AesUtil.aesEncrypt(tUserRes.getLoginName(),AES_KEY));
			} catch (Exception e) {
				e.printStackTrace();
			}
			//两个小时的有效期
			session.setMaxInactiveInterval(7200);
			
			//获取最新权限缓存
			tMenuService.getMenuUrlByloginName(tUserRes.getLoginName());
			
			return	ResponseData.success(tUserRes.getUserName());
		}else {
			
			log.error(TUserConstant.LOGIN_PSW_ERROR);
			return ResponseData.error(TUserConstant.LOGIN_PSW_ERROR);
		}
	}

五、单点登录

作为登录功能因为所有的系统都需要登录,往往我们就可以把登录功能封装处理供所有的系统使用。我们可以把它作为一个登录系统或者认证中心,也可以作为单点登录。

单点登录的原理:

 

 关于单点登录,我会上传一份源码到资源。开箱即用。

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

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

相关文章

前端开发中移动端开发需要注意什么? - 易智编译EaseEditing

在前端开发中&#xff0c;移动端开发具有一些独特的挑战和注意事项。以下是移动端开发时需要注意的一些重要点&#xff1a; 响应式设计&#xff1a; 移动设备的屏幕尺寸和分辨率多样&#xff0c;因此要采用响应式设计&#xff0c;确保你的网站或应用在各种设备上都能良好地呈…

Star History 月度开源精选|Llama 2 及周边生态特辑

7 月 18 日&#xff0c;Meta 发布了 Llama&#xff0c;大语言模型 Llama 1 的进阶版&#xff0c;可以自由免费用于研究和商业&#xff0c;支持私有化部署。 所以本期 Star History 的主题是&#xff1a;帮助你快速把 Llama 2 在自己机器上跑起来的开源工具&#xff0c;无论你的…

生信学院|08月25日《SOLIDWORKS PDM帮助企业对设计数据版本的管理应用》

课程主题&#xff1a;SOLIDWORKS PDM帮助企业对设计数据版本的管理应用 课程时间&#xff1a;2023年08月25日 14:00-14:30 主讲人&#xff1a;车立洋 生信科技 PDM专家 1、图纸&文档的版本管理对于企业的重要性 2、SolidWorks PDM对图纸&文档版本的管理 3、SolidW…

浅析阿里云灵积(平台)模型服务

简介&#xff1a; DashScope灵积模型服务以模型为中心&#xff0c;致力于面向AI应用开发者提供品类丰富、数量众多的模型选择&#xff0c;并为其提供开箱即用、能力卓越、成本经济的模型服务API。DashScope灵积模型服务依托达摩院等机构的优质模型&#xff0c;在阿里云基础设施…

Ubuntu22.04利用lightdm替换gdm3出现的问题或Bug

Ubuntu22.04利用lightdm替换gdm3出现的问题或Bug 问题1&#xff1a;快捷键无法使用问题2&#xff1a;qq_music打开失败问题3&#xff1a;微信截图收发文件的解决问题4&#xff1a;Dock以及plank问题的解决随时更新补充中ing... 问题1&#xff1a;快捷键无法使用 修复输入法的问…

【VR】SteamVR2.0的示例场景在哪里

&#x1f4a6;本专栏是我关于VR开发的笔记 &#x1f236;本篇是——在哪里可以找到SteamVR2.0的示例场景 SteamVR2.0的示例场景在哪里 1. 逐步打开方式2. 快速打开方式 1. 逐步打开方式 Assets——SteamVR——InteractionSystem——Samples——>Interactions_Example 2. 快…

17.8k Star!开源且支持私有化部署的碎片化知识卡片管理工具-Memos

应用简览 Memos 是一个开源的轻量级笔记服务应用&#xff0c;它为用户提供了一个随时记录思绪和想法的私密空间&#xff0c;同时它支持私有化部署&#xff0c;这意味你可以完全掌控你的数据和隐私&#xff0c;同时它还提供了直观的分享功能&#xff0c;让你可以轻松地与他人协作…

用 Audacity 比较两段音频差异

工作中遇到相同的处理流程&#xff0c;处理同一段音频&#xff0c;看看处理结果是否一致&#xff0c;可以用audacity来处理。 假设待比较的音频分别为 1.wav 2.wav 1、用Audacity打开1.wav 2、用Audacity打开2.wav&#xff0c;选中音频&#xff0c;然后用 效果 -> 反向&am…

React项目build打包后,页面空白的解决方案

问题描述&#xff1a; React项目执行 build 命令后&#xff0c;在本地服务器打开页面 是空白的&#xff0c;而且控制台报错 如下图所示 解决方法 打开根目录下的 package.json 文件&#xff0c;添加如下代码 {"name": "testproject","version"…

冠达管理:创业板指是什么意思啊?

跟着我国经济的不断开展&#xff0c;越来越多的人开始进入股票商场。作为一个出资新手&#xff0c;你可能会对股票商场上的各种术语感到困惑&#xff0c;比方创业板指。 创业板指是什么&#xff1f; 创业板指是我国证监会于2009年6月1日推出的第二个股票指数&#xff0c;旨在衡…

公司核心文件数据防泄密系统——「天锐绿盾加密软件」

企业内每日的文档传输可能会发生成千上万次以上&#xff0c;已经成为最容易泄密的环节。在日常工作中&#xff0c;我们无法避免通过即时通讯工具、网络、邮件、移动设备等方式传输机密文档&#xff0c;那么我们该如何保障文档传输安全呢&#xff1f;为此天锐绿盾终端管理系统提…

如何优化因为高亮造成的大文本(大字段)检索缓慢问题

首先还是说一下背景&#xff0c;工作中用到了 elasticsearch 的检索以及高亮展示&#xff0c;但是索引中的content字段是读取的大文本内容&#xff0c;所以后果就是索引的单个字段很大&#xff0c;造成单独检索请求的时候速度还可以&#xff0c;但是加入高亮之后检索请求的耗时…

最新议程 | OffiSmart智慧办公及空间管理峰会

【OffiSmart智慧办公及空间管理峰会】是SSOT旗下品牌高峰论坛&#xff0c;自2019年在展会现场同期推出以来&#xff0c;邀请众多专家学者、企业高管、从业人员参与其中&#xff0c;收到行业多方称赞。 今年规模和精彩程度再度升级&#xff0c;覆盖所有人群和细分领域。以用户为…

计算机视觉入门 6) 数据集增强(Data Augmentation)

系列文章目录 计算机视觉入门 1&#xff09;卷积分类器计算机视觉入门 2&#xff09;卷积和ReLU计算机视觉入门 3&#xff09;最大池化计算机视觉入门 4&#xff09;滑动窗口计算机视觉入门 5&#xff09;自定义卷积网络计算机视觉入门 6&#xff09; 数据集增强&#xff08;D…

jvs-rules(规则引擎)更新:新增功能介绍

jvs-rules更新内容 1.复合变量新增数据补充节点&#xff0c;实现请求回来的数据再以入参方式请求其他数据进行数据补充&#xff08;例如通过参数A&#xff0c;请求回数据B&#xff0c;再以数据B为入参&#xff0c;请求回数据C&#xff09; 2.规则流结束节点支持新增、新建、引…

【算法】活用双指针完成复写零操作

Problem: 1089. 复写零 文章目录 题目解析算法原理分析找到最后一个复写的位置从后往前进行复写操作 代码展示 题目解析 首先我们来分析一下本题的题目意思 可以看到题目中给到了一个数组&#xff0c;意思是让我们将数组中的零元素都复写一遍&#xff0c;然后将其余的元素向后平…

细菌感染后抗生素耐药性如何形成以及预测抗生素对肠道菌群的影响

谷禾健康 抗生素耐药性是当下和未来几十年人类健康将面临的重要挑战之一。从2000年到2015年&#xff0c;抗菌药物的普及导致人类抗生素消耗量增加了约65%&#xff0c;2015年后这个数据还在增加。最明显的后果是抗生素耐药性的增多&#xff0c;这使得近年来常见的感染难以治疗。…

网络聊天室

一、项目要求 利用UDP协议&#xff0c;实现一套聊天室软件。服务器端记录客户端的地址&#xff0c;客户端发送消息后&#xff0c;服务器群发给各个客户端软件。 问题思考 客户端会不会知道其它客户端地址&#xff1f; UDP客户端不会直接互连&#xff0c;所以不会获知其它客…

Flutter对象状态动态监听Watcher

场景&#xff1a;当一个表单需要在表单全部或者特定项赋值后才会让提交按钮可点击。 1.普通实现方式&#xff1a; ///场景&#xff1a;检查[test11][test12][test13]均不为空时做一些事情&#xff0c;例如提交按钮变成可点击String? test11;String? test12;int? test13;///当…

Linux后门大全-xinetd后门(二)

环境 靶机&#xff1a;centos7.6 攻击机&#xff1a;Linux 使用docker搭建靶机环境&#xff0c;当然也可以不使用docker&#xff0c;直接跳过创建容器的步骤即可 创建容器 #创建名为backdoorT4的特权容器&#xff0c;并使用/usr/sbin/init&#xff0c;因为容器默认不开启sy…