环境需求:redis3.8.2+maven+springBoot+jdk1.8+freemarker模板
1、需求背景
周末在家,上家同事突然联系,让我给他网站做单点登入功能,于是自己先梳理逻辑,实现功能并且记录下来。
单点登入(Single sign on)顾名思义,就是在一个网站登入之后,其他网站就不需要用户继续输入账号密码,而能免密登入,这种技术在大型网站都使用的非常频繁,比如阿里巴巴,当用户登入他们系统后,每个子系统都能自动登入,如果大家在登入某宝之后,登入某碑,也需要密码,登入淘宝也需要重新输入密码,这肯定会造成用户体验极差,而且系统的认证逻辑也会很麻烦,这时候单点登入就出现了。
2、代码实例
本文演示两个系统
@Slf4j
@RestController
@RequestMapping("/redis/single")
public class RedisSingleController {
private static final String NAME = "name";
private static final String PASSWORD = "password";
@Resource
private RedisTemplate redisTemplate;
@GetMapping("/login_page")
public ModelAndView loginPage(){
ModelAndView mv = new ModelAndView();
mv.setViewName("loginPage");
return mv;
}
/**
* 系统1
* @return
*/
@GetMapping("/system1")
public ModelAndView system1(HttpServletRequest request){
ModelAndView mv = new ModelAndView();
if(redisTemplate.hasKey("name")){
mv.setViewName("systemOnePage");
return mv;
}
request.getSession().setAttribute("goUrl","indexSystem1");
mv.setViewName("loginPage");
return mv;
}
/**
* 系统2
* @return
*/
@GetMapping("/system2")
public ModelAndView system2(HttpServletRequest request){
ModelAndView mv = new ModelAndView();
if(redisTemplate.hasKey("name")){
mv.setViewName("systemTwoPage");
return mv;
}
request.getSession().setAttribute("goUrl","indexSystem2");
mv.setViewName("loginPage");
return mv;
}
/**
* 效验账号密码是否正常
* @param name
* @param password
* @return
*/
@PostMapping("/detection")
@ResponseBody
public Map<String, Object> index( String name, String password, String gotoUrl){
Map<String, Object> map = new HashMap<>();
if(!ObjectUtil.equals(name,NAME) || !ObjectUtil.equals(password,PASSWORD)){
map.put("flag",false);
map.put("data","账号密码不匹配!");
return map;
}
map.put("flag",true);
map.put("data","账号密码正确!");
HttpSession session = request.getSession();
session.setAttribute("name",name);
//redis缓存20s失效
redisTemplate.opsForValue().set("name",name,10, TimeUnit.SECONDS);
return map;
}
/**
* 登入成功,系统一进入首页
* @return
*/
@GetMapping("/indexSystem1")
@ResponseBody
public ModelAndView index(){
ModelAndView mv = new ModelAndView();
mv.setViewName("systemOnePage");
return mv;
}
/**
* 登入成功,系统二进入首页
* @return
*/
@GetMapping("/indexSystem2")
@ResponseBody
public ModelAndView indexSystem2(){
ModelAndView mv = new ModelAndView();
mv.setViewName("systemTwoPage");
return mv;
}
1、保证访问系统一登入页面时,进入的是系统一首页,访问系统二登入页面时,进入的是系统二首页。
2、在访问系统一或者系统二时,都需要判断redis里是否存在当前用户,存在则免密登入。
3、逻辑处理,在登入先判断数据库里的账号密码是否正确,若用户在页面登入正确,则返回登入成功,并且存入redis,给他设置过期时间。
4、保证在redis过期时间内其他子系统都能免密登入。
springBoot+redis实现登入拦截器--系统框架搭建(二)
https://blog.csdn.net/ke1ying/article/details/117822312?spm=1001.2014.3001.5501
最后,看到这里的读者,如果喜欢的话安排一波(点赞,收藏,关注),原创不易,每周定期分享小知识。