后端实现用户登录验证和同时只能允许一个用户登录
之前网上看了一些文章又是redis又是Cookie的感觉没有必要
现实中遇见大神好多,但是网上的文章写的却不咋地,可能大神很忙,没时间写吧。
废话不多说
思路:
用户登录校验思路:
1.将登录的用户信息放在session中
2.每次请求过来的数据对他进行校验看session中是否存在用户信息,没有就返回首页
用户校验+只允许一个用户登录该系统思路:
1.将登录的用户信息放在session中
2.每次请求过来的数据对他进行校验:
2.1看session中是否存在用户信息,没有就返回首页
2.2如果有看他的session中保存的用户的sessionId是否和数据库中当前用户的sessionId相同
相同:通过他的请求
不同:注销请求过来的session并返回首页,提醒用户,该账户在其他地方登录。
代码实现:
1.用户登录
这里的用户名和密码是要前端获取的,我这样写只是为了好测试。
setMaxInactiveInterval()是设置session过期时间的,单位秒
/** *用户登录 */ @GetMapping("/login") public String login(HttpServletRequest request){ HttpSession session = request.getSession(); // User user=new User(); // user.setName("张三"); // user.setPassword("123456"); QueryWrapper<User> wrapper = new QueryWrapper<>(); User user1 = new User(); user1.setName("张三"); user1.setPassword("123456"); wrapper.setEntity(user1); User one = userService.getOne(wrapper); if(one==null){ return "登陆失败"; } one.setSessionId(session.getId()); //更新登录状态 userService.saveOrUpdate(one); session.setAttribute("user",one); // session.setMaxInactiveInterval(10); // setMaxInactiveInterval(int i) // i的单位是秒。 // 如果设置的值为零或负数,则表示会话将永远不会超时。常用于设置当前会话时间。 return "ok"; }
2.用户校验
这里校验分2中:
1.判断用户是否登录
2.判断当前的请求中用户是否在其他地方已经登陆了
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.could.demo.entity.User; import com.could.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * AUTHOR :zhao * 日期:2020/3/20 18:48 * 用户登录校验 * HandlerInterceptorAdapter相当于一个Filter拦截器,但是这个颗粒度更细,能使用Spring的@Autowired注入。 */ @Component public class HandlerInterceptorConfigurer extends HandlerInterceptorAdapter { /** *preHandle在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制等处理; * postHandle在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView; * afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面),可以根据ex是否为null判断是否发生了异常,进行日志记录; */ @Autowired private UserService userService; /** * 判断用户是否登录 通过session 实现 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); User user = (User) session.getAttribute("user"); if (user != null){ QueryWrapper<User> wrapper = new QueryWrapper<>(); User user1 = new User(); user1.setName(user.getName()); wrapper.setEntity(user1); User one = userService.getOne(wrapper); /** * 登录过的用户分2中 * 1.登录被挤下去的 * 2.刚登陆的 */ //1. /** * 如果是登录页面让进来 * 如果当前请求的sessionId和存在user表中的id不一样给他说该账号在其他地方已经登陆了 */ //如果当前的用户sessionid不等于数据库中的sessionid if(!session.getId().equals(one.getSessionId())){ session.invalidate(); // 跳转登录 String url = "/index"; //表示该用户没有登录,输出 出错信息 // PrintWriter out = null; // try{ // response.setHeader("Content-type", "text/html;charset=UTF-8"); // out = response.getWriter(); // out.append("{\"success\":false,\"code\":SOS,\"msg\":\"您的账号在其他地方登录请您重新登陆\"}"); //// response.sendRedirect(url); // }catch(IOException e){ // e.printStackTrace(); // }finally { // if (out != null) { // out.close(); // } // } response.sendRedirect(url); return false; } //2. // QueryWrapper<User> wrapper = new QueryWrapper<>(); // User user1 = new User(); // user1.setName(user.getName()); // wrapper.setEntity(user1); // User one = userService.getOne(wrapper); // if(one!=null&&user.getPassword().equals(one.getPassword())){ return true; // } } // 跳转登录 String url = "/index"; response.sendRedirect(url); return false; } }
3.用户注销
invalidate()方法清空session对象 removeAttribute() 清空session对象中的变量
@GetMapping("/logout")
public String add(HttpServletRequest request, HttpServletResponse response,HttpSession session1){
//System.out.println(session1.getId());
session1.invalidate();
// session1.removeAttribute("user"); //清空Session变量
return "注销成功";
}
4.返回首页
getSession(false) 判断当前的session是否存在,存在返回当前对象不存在返回null。
/** *首页 */ @GetMapping("/index") public String index(HttpServletRequest request){ if(request.getSession(false)==null){ return "您的账号已退出或在其他地方登录,请重新登陆"; } return "首页"; }
好了收工。
缺点:session保存东西越小越好,毕竟占服务器内存!
sessionId能被用户看见



浙公网安备 33010602011771号