实现用户在浏览器登录后,跳转到其他页面,当用户在其它地方又登录时,前面用户登录的页面退出登录(列如qq挤号那种方式)
用户在前端填写用户信息登录后,后台接收数据先去数据库进行判断,如果登录成功,创建映射集合,以用户id为键,令牌为值,先通过当前登录用户的身份去获取令牌,如果牌存在说明该用户已经登录过,调用复述,以令牌为键删除上个用户的信息,调用方法生成新令牌,并将牌存入映射集合,将用户信息存入复述,并将牌存入饼干。当用户回到前面登录的页面时,刷新页面,调用方法,通过后端获取饼干的令牌值,通过令牌在复述中查询用户信息是否存在,如果不存在,前端通过返回值判断重新回到登录页面!
后端:
1,创建SpringBoot项目,创建用户表,由于是通过Vue编写的,所以是前后端分离,需要跨域,我这里编写了跨域配置类,还有复述的util类,返回的封装类,饼干的util类,文末有源码提供,可以自行提取。
2,百胜配置文件
春天: 复述: 数据库:0 #复述的默认数据库为0 主持人:127.0.0.1 #链接复述的ip 端口:6379 #链接复述的端口号 密码:#链接复述的密码默认为空 能: 池: max-total: 200 #链接复述的总数目 max-active: 100 #链接复述的最大 最大空闲:8 #最大的链接数量 min-idle: 5 #最小的链接数量 数据源: url: jdbc: mysql://127.0.0.1:3306/测试# 63;useUnicode=true 用户名:根 密码:根 driver-class-name: com.mysql.jdbc.Driver jpa: show-sql:真 服务器: 端口:8888 REDIS_KEY: USER_TOKEN
3,编写实体User.class
@ data @ entity @ table (name="用户") 公开课用户{ @ id @ column (name=" id ",独特的=true, nullable=false) 私人int id; @ column (name="用户名",nullable=false) 私人字符串的用户名; @ column (name="密码",nullable=false) 私人密码字符串; }
4,编写刀,UserDao.class
公共接口UserDao延伸JpaRepository<用户,Integer>{ 公共用户findByUsernameAndPassword(用户名的字符串,字符串密码); }
5,编写serviceImpl, UserServiceImpl.class进行登录的业务逻辑处理
@ service 公开课UserServiceImpl { @ autowired 私人UserDao UserDao; @ autowired 私人JedisDao JedisDao; @ value (" $ {REDIS_KEY} ")//从配置文件中取的值 私人字符串键; 私人Map<整数,String>,UserLogin=new HashMap<的在();/* * * 登录 * @param请求 * @param响应 * @param u * @return */公共用户userlogin (HttpServletRequest请求,HttpServletResponse响应用户u) {//查询登录是否成功 用户用户=userDao.findByUsernameAndPassword (u.getUsername (), u.getPassword ());//判断我们是否为空 如果(用户==null) { 返回null; }//生成令牌 字符串标记=" user_ " + UUID.randomUUID () .toString ();//从地图中获得复述中的关键 字符串oldToken=UserLogin.get (user.getId ());//判断地图中是否存在该id 如果(! StringUtils.isEmpty (oldToken)) {//删除复述中老的值 jedisDao.delValue (oldToken); }//将新的的关键保存到映射中 UserLogin.put (user.getId(),令牌);//将信息存入复述 jedisDao。setValue(令牌,JsonUtils.objectToJson(用户));//将牌放入cookie中 CookieUtils.setCookie(请求、响应关键牌5 * 60,true); 返回用户; }/* * * 判断是否登录 * @param响应 * @param请求 * @return */公共字符串getUserByToken (HttpServletResponse反应,HttpServletRequest请求){//从cookie中取出用户令牌 字符串标记=CookieUtils.getCookieValue(请求,关键);//从复述中取出用户信息 字符串的用户=jedisDao.getValue(令牌); 返回用户; } }
6,编写控制器,接收前端请求,返回数据
@RestController 公开课LoginController { @ autowired 私人UserServiceImpl userService;/* * * 登录 * @param响应 * @param请求 * @param用户 * @param模型 * @return */@PostMapping("/登录”) 公共ResponseResult登录(HttpServletResponse响应,HttpServletRequest请求,@RequestBody用户用户模型模型){ ResponseResult ResponseResult=new ResponseResult (); 尝试{ 用户user2=userService。userlogin(请求、响应用户); 如果(user2 !=null) { responseResult.setState (200); responseResult.setMsg(“登录成功!”); 返回responseResult; 其他}{ responseResult.setState (202); responseResult.setMsg(“用户名或密码错误!”); 返回responseResult; } }捕捉(异常e) { responseResult.setState (500); responseResult.setMsg(“发生错误,登录失败!”); 返回responseResult; } }/* * * 判断是否登录 * @param响应 * @param请求 * @return * @throws例外 */@GetMapping ("/toLogin”) 公共ResponseResult getUserInfo (HttpServletResponse反应,HttpServletRequest请求){抛出异常 ResponseResult ResponseResult=new ResponseResult (); 尝试{ 令牌=userService字符串。getUserByToken(响应,请求); 如果(令牌!=null) { responseResult.setState (200); responseResult.setMsg(“登录中!”); 返回responseResult; 其他}{ responseResult.setState (202); responseResult.setMsg(“在别处登录!”); 返回responseResult; } }捕捉(异常e) { response.setStatus (500); responseResult.setMsg(“发生错误!”); 返回responseResult; } } }SpringBoot + Vue +复述,实现单点登录(一处登录另一处退出登录)