简介:
SSO英文全称Single Sign On。
单点登录是一种控制多个相关但彼此独立的系统访问权限的机制, 拥有这一权限的用户。
可以使用单一的ID和密码访问某个或多个系统从而避免使用不同的用户名或密码,或者通过某种配置无缝地登录每个系统,它是目前比较流行的企业业务整合的解决方案之一,例如我们使用mis号登陆过公司的一个系统后,再登陆其他系统不用再次输入用户名和密码
没想的那么复杂,就是你这边登录之后存到session或者存到reds里面存一个值,然后有另外一次再来登录的时候先判断下session或reds上面有没有值,如果有的就把原先的清除掉呃,或者是把修改掉,然后这边就那边就会失效了。
项目结构
我这个使用的是jpa来查询和mybatis差不多
依赖
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.7.5
com.springboot
jpa
0.0.1-SNAPSHOT
jpa
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
com.mysql
mysql-connector-j
runtime
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
com.baomidou
mybatis-plus-boot-starter
3.5.2
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
Controller层
@Controller
public class goodsController {
@Autowired
private dddService dddService;
@RequestMapping("/")
public String tologin(){
return "login";
}
@RequestMapping("/login")
public String login(HttpSession session , User user, Model model, ddd ddd){
if (!StringUtils.isEmpty(user.getUserName()) && "123456".equals(user.getPassword())) {
Random r = new Random();
int num =0;
for (int i = 1; i < 8; i++) {
num += r.nextInt(9); // 生成[0,9]区间的整数
}
ddd.setId(1);
ddd.setIDD(num);
dddService.save(ddd);
ddd ddd1=dddService.getId(1);
System.out.println(ddd1.toString());
//把登录成功的用户保存起来
if (session.getAttribute("loginUser")!=null){
//如果有session代表已经被登录了,所以把session改掉或者把 session删掉
session.setAttribute("loginUser",num+99);
}else {
session.setAttribute("loginUser",num);
}
//登录成功重定向到main.html,重定向防止表单重复提交
return "redirect:/1";
}else {
model.addAttribute("msg","账号密码错误");
//回到登录页面
return "login";
}
}
@RequestMapping("/gogo")
public String gogo(Model model){
model.addAttribute("msg","没有问题");
return "redirect:/1";
}
这里判断的session存不存在的时候我建议是存在的时候把session删掉而不是修改,因为修改有点麻烦
这一段都是修改的准备
接口层和实现
一个是根据id查询 还有一个是更新,更新用的是jpa封装的方法
查询是注解写的
数据库
这个表中的数据就是要用来判断,不想这么麻烦就选择删除session
拦截器
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
@Autowired
private com.springboot.mapper.dddMapper dddMapper;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor(dddMapper))
.addPathPatterns("/gogo")//所有的请求都被拦截包括静态资源
.excludePathPatterns("/","/login");//放行的请求
}
}
拦截器方法
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
private dddMapper dddMapper;
public LoginInterceptor(dddMapper dddMapper){
this.dddMapper=dddMapper;
}
/**
*目标方法执行之前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI=request.getRequestURI();
log.info("拦截的请求路径是{}",requestURI);
//登录检查逻辑
HttpSession session=request.getSession();
Object loginUser=session.getAttribute("loginUser");
if (loginUser!=null){
int num=(int)loginUser;
ddd ddd=dddMapper.getId(1);
if (num==ddd.getIDD()){
//放行
return true;
}
request.setAttribute("msg","以被别人登录");
request.getRequestDispatcher("/").forward(request,response);
return false;
}
//拦截住,未登录, 跳转到登录页
request.setAttribute("msg","请重新登录");
request.getRequestDispatcher("/").forward(request,response);
return false;
}
/**
* 目标方法执行完成以后
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("postHandle执行{}",modelAndView);
}
/**
* 页面渲染之后
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("afterCompletion执行异常{}",ex);
}
}
如果我们从数据库取出来的值和session中的值不一样 说明已经别登录了
还有这边有一个注意点 直接使用
dddMapper.getId(1);会报空指针
所以我们要手动注入bean
你使用mybatis 也需要这一步
再打开一个页面登录
原页面点击测试
页面
Title
就这么简单的实现出来了 谢谢大家观看 可能有点迷惑 我也是参考两位大佬的代码所实现的 难免有bug和纰漏
如果你想使用Redis缓存实现可以参考两位大佬的文章,对你们应该有帮助
大佬1:https://blog.csdn.net/weixin_64705033/article/details/128032094?spm=1001.2014.3001.5502
大佬2:https://blog.csdn.net/sbw17608463386/article/details/103257193?spm=1001.2014.3001.5502
希望这两位的文章对你们有帮助