Management system user login function

I. Introduction

Any management information system will have a login function. We can simply log in through username, password and verification code. But even such a simple function involves many requirements.

For example, the requirements for the account number, the complexity of the password, the duration of the login, the validity period of the password, the record of the login log of the logged-in user, the permissions of the logged-in user, and so on. Very, very much. This article introduces the simple login function.

2. Login function database table design


-- 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)
);

 3. Registered users

Registered users are divided into the following steps

1. Determine whether the newly added user exists. If there is a user who is not allowed to register the same account

2. Determine whether the username and password are empty

3. Verify that the password complexity is a composite requirement

4. Encrypt the password

5. Report an error when registering a new administrator account

/**
	 * 保存后台管理用户信息
	 * @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);
		}
	}

Password complexity function:

/**
	 * 校验复杂度
	 */
	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);
	}

4. User login

1. Limit frequent login operations

2. Check code verification

3. Verify that the user and password are correct

4. Determine whether the password has expired and whether it needs to be reset.

5. Write the login information to the cache and set it to expire after 2 hours of inactivity.

6. Obtain the permissions of the logged in user

Code example:

/**
	 * 后台管理用户登录
	 * @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);
		}
	}

5. Single sign-on

As a login function, because all systems require login, we can often encapsulate the login function for use by all systems. We can use it as a login system or authentication center, or as a single sign-on.

The principle of single sign-on:

 

 Regarding single sign-on, I will upload a source code to the resource. Ready to use right out of the box.

Guess you like

Origin blog.csdn.net/dongjing991/article/details/132446679