登录解决方案-单体应用-Session登录(拦截器实现)-实现一个简单的登录
一、技术栈:
SpringBoot + thymeleaf 前后不分离
常用注解:@RequiredArgsConstructor lombok的注解 标注了 此注解 获取相关bean对象时 不需要 再用@Autowird 进行依赖注入
二、前期准备
需求
- 实现一个简单的登录
- 用户登录首页后进入登录页默认进入首页 + Aop加自定义注解 对每个接口进行访问控制
- 单点登录,同一账号 在A浏览器登录后 在B浏览器登录上将 A挤下来,跨机房(服务器)单点签退
表
/* 适用数据库:MYSQL 修改内容 创建用户表 最后修改人:mangoubiubiu 最后修改日期:2022.03.27 */ CREATE TABLE huas_user ( id VARCHAR(32) NOT NULL COMMENT '用户唯一id', oauth_id VARCHAR(32) COMMENT '第三方登录应用id', oauth_type VARCHAR(16) COMMENT '第三方应用名', user_name VARCHAR(32) DEFAULT 'huas' COMMENT '用户名', nickname VARCHAR(64) COMMENT '用户昵称', pwd VARCHAR(32) NOT NULL COMMENT '用户密码', email VARCHAR(50) COMMENT '用户邮箱', avatar VARCHAR(1000) COMMENT '用户头像', signature VARCHAR(1000) COMMENT '个性签名' , phone VARCHAR(11) COMMENT '用户手机', sex VARCHAR(3) COMMENT '性别 1 男 0女', is_deleted TINYINT(1) UNSIGNED NOT NULL COMMENT '逻辑删除 1(true)已删除, 0(false)', update_time VARCHAR (14) COMMENT '修改时间', create_time VARCHAR (14) COMMENT '创建时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- Add comments to the table ALTER TABLE huas_user ADD CONSTRAINT HUAS_USER_KEY PRIMARY KEY (id); COMMIT; /* 适用数据库:MYSQL 修改内容 创建session信息表 最后修改人:mangoubiubiu 最后修改日期:2022.03.27 */ CREATE TABLE huas_sessionid ( id VARCHAR(32) NOT NULL COMMENT '主键', user_id VARCHAR(32) NOT NULL COMMENT '用户id', session_id VARCHAR(32) COMMENT '用户登录的session_id', addr VARCHAR(15) COMMENT '用户请求的地址', port VARCHAR(12) COMMENT '请求的ip', update_time VARCHAR (14) COMMENT '修改时间', create_time VARCHAR (14) COMMENT '创建时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- Add comments to the table ALTER TABLE huas_sessionid ADD CONSTRAINT HUAS_SESSION_KEY PRIMARY KEY (id); COMMIT;
三、需求实现
1、实现一个简单的登录
利用Session进行登录,其实很简单,先校验完用户信息后将用户信息存Session,再是对用户的所有请求进行判断,看用户当前请求Session里有没有用户信息。
如何对用户所有的请求进行拦截校验,有几种解决方案。
一、是写一个BaseController,写一个对Session校验的方法,然后后面需要判断用户是否登录的Controller 都继承这个类,然后用这个方法在每个请求方法里进行手动校验,有一说一,非常不推荐,太繁琐冗余。
import javax.servlet.http.HttpServletRequest; public class BaseController { protected boolean checkLogin(HttpServletRequest request) { System.out.println("==BaseController===checkLogin=="); boolean flag= request.getSession().getAttribute("loginStatus")==null?false:(boolean)request.getSession().getAttribute("loginStatus"); return flag; } }
@Controller @RequestMapping({"/login", "/"}) public class LoginController extends BaseController{ @Autowired HttpServletRequest request; @Autowired LoginService loginService; @RequestMapping({"/index", "/"}) public String index(){ Boolean loginStatus=(Boolean) request.getSession().getAttribute("loginStatus"); if(loginStatus!=null&&loginStatus) return "home/index"; return login(); } }
二、是写一个拦截器,对指定请求进行登录拦截,看当前请求有没有用户信息,有就放行,没有就转发到登录页面。
1、MvcController 类 用户前端页面跳转
package com.mangoubiubiu.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller @RequestMapping("/mvc") public class MvcController { @GetMapping(value = "/index") public String index(HttpServletRequest request){ return "/login"; } @GetMapping(value = "/l/admin") public String admin(HttpServletRequest request){ return "/admin"; } }
2、登录Controller
package com.mangoubiubiu.controller; import com.mangoubiubiu.annotation.Auth; import com.mangoubiubiu.entities.HuasUser; import com.mangoubiubiu.event.SessionIdEvent; import com.mangoubiubiu.exception.BusinessException; import com.mangoubiubiu.exception.CommonErrorCode; import com.mangoubiubiu.service.LoginService; import com.mangoubiubiu.utils.R; import com.mangoubiubiu.vo.UserLogin; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.context.ApplicationEventPublisher; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @Api(tags = "登录模快") @RestController @RequestMapping("/user") @RequiredArgsConstructor public class LoginController { final ApplicationEventPublisher context; final LoginService loginService; @ApiImplicitParam(name = "userLogin",value = "用户信息",required = true) @ApiOperation(value = "登录接口") @PostMapping("/login") public R login(@RequestBody UserLogin userLogin){ boolean flag = false; String type = userLogin.getType(); if(StringUtils.isBlank(type)){ throw new BusinessException(CommonErrorCode.E_100101); } //账号密码登录 if("0".equals(type)){ flag= loginService.loginByPwd(userLogin); //验证码登录 }else if("1".equals(type)){ flag= loginService.loginByPhone(userLogin); } return flag==true?R.ok():R.error().message("登录失败"); } }
3、登录Service
package com.mangoubiubiu.service.impl; import com.mangoubiubiu.entities.HuasUser; import com.mangoubiubiu.enums.SessionCodeEnum; import com.mangoubiubiu.event.SessionIdEvent; import com.mangoubiubiu.event.UserSingOutEvent; import com.mangoubiubiu.exception.BusinessException; import com.mangoubiubiu.exception.CommonErrorCode; import com.mangoubiubiu.mapper.HuasUserMapper; import com.mangoubiubiu.service.LoginService; import com.mangoubiubiu.service.SessionService; import com.mangoubiubiu.utils.PasswordUtil; import com.mangoubiubiu.vo.UserLogin; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @Service @RequiredArgsConstructor public class LoginServiceImpl implements LoginService { final ApplicationEventPublisher context; final HuasUserMapper mapper; final SessionService sessionService; @Override public boolean loginByPwd(UserLogin userLogin) { String account = userLogin.getAccount(); String pwd= userLogin.getPwd(); if(StringUtils.isBlank(account) || StringUtils.isBlank(pwd)){ throw new BusinessException(CommonErrorCode.E_100101); } HuasUser huasUser = mapper.selectByAccount(account); //用户不存在 if(huasUser==null){ throw new BusinessException(CommonErrorCode.U_900102); } System.out.println(huasUser.toString()); //校验密码 boolean verify = PasswordUtil.verify(pwd, huasUser.getPwd()); if(!verify){ throw new BusinessException(CommonErrorCode.U_900103); } //保存session sessionService.saveSession(huasUser); return true; } @Override public boolean loginByPhone(UserLogin userLogin) { return false; } }
4、拦截器
package com.mangoubiubiu.intercepter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.mangoubiubiu.entities.HuasUser; import com.mangoubiubiu.enums.SessionCodeEnum; import com.mangoubiubiu.service.SessionService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @Component @RequiredArgsConstructor public class LoginInterceptor implements HandlerInterceptor { final SessionService sessionService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HuasUser user=(HuasUser)request.getSession().getAttribute(SessionCodeEnum.USER_INFO.getKey()); String servletPath = request.getServletPath(); //如果当前请求页是登录页 跳转到首页 if("/mvc/index".equals(servletPath) ){ if (user!=null) { System.out.println("/mvc/index"); request.getRequestDispatcher("/mvc/l/admin").forward(request, response); } return true; } //用户已登录 if (user!=null) { //如果用户状态改变了 移除当前session if("1".equals(user.getUserLogFlag())){ sessionService.removieSession(); } //放行 return true; } request.getRequestDispatcher("/mvc/index").forward(request, response); //重定向到登录页面 return false; } }
package com.mangoubiubiu.conf; import com.mangoubiubiu.intercepter.LoginInterceptor; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { final LoginInterceptor interceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 添加拦截器,配置拦截地址 registry.addInterceptor(interceptor).addPathPatterns("/mvc/**"); // registry.addInterceptor(interceptor).addPathPatterns("/user/**"); } }
5、前端页面Ajax
$.ajax({
type:"POST",
dataType: "json",
contentType:'application/json;charset=UTF-8', //设置后
url:"/huas/user/login",
//指定
data: JSON.stringify(param),
//预期服务器返回的数据类型
//服务器响应成功时候的回调函数
success:function(result){
if(result.code==20000){
window.location = "/huas/mvc/l/admin";
}else if(result.code== "900102"){
$("#loginSpanTips").html( "*"+result.message+"!");
}else if(result.code == "900103"){
$("#pwdSpanTips").html( "*"+result.message+"!");
}else{
$("#loginSpanTips").html( "*未知错误");
}
},error:function(xhr, textStatus, err){//服务器响应失败时候的回调函数
}
})
四、测试 此页面为毕业设计页面。。。。。
查到校验存 Session 成功
本文作者:KwFruit
本文链接:https://www.cnblogs.com/mangoubiubiu/p/16102552.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步