首先先解释一下自己的实现的思路,我使用的是后端从前台获取浏览器的cookie信息,从数据库中得到相应的cookie保存的数据,我两边保存的是通过uuid生成的token的令牌,以此来比对当前cookie的token和数据库中的token是否相同,如果相同,者直接放行,如果不相同,则代表这个账号被其他地方所登录,改写了数据库中相应的token,所以导致不一致,如果要登录的话就要重新登录,重新将保存的cookie的token的值持久化到数据库中。实现的部分代码如下
public Message isLonginSuccess(UserLogin currUser,
HttpServletRequest request, HttpServletResponse response) {
Message msg=new Message();
//查找密码与自己校验
UserLogin login = userLoginMapper.findUserLoginByUserAccount(currUser.getUserAccount());
//存在用户
if(login!=null){
//首先判断这个用户是否可用
if(isWriteOff(login)){
throw new ExceptionMessage("此用户已被注销,不可使用,登陆失败");
}
//密码验证成功
if(login.getUserPassword()!=null&&login.getUserPassword().equals(currUser.getUserPassword())){
//查找当前的cookie是不是已经存在
//将令牌拿出来,假设设置cookie为token为当地cookie的值
String token=login.getToken();
Cookie[] userCookie = request.getCookies();
if(userCookie!=null&&userCookie.length>0){
for (Cookie cookie : userCookie) {
//查找是不是存在当前的cookie
if("token".equals(cookie.getName())){
String currCookieValue=cookie.getValue();
//查找当前的cookie的值是不是数据库保存的值
if(currCookieValue.equals(token)){
msg.setStatu(1);
login.setUserPassword(null);
//将当前用户的账号和姓名保存在session中、
request.getSession().setAttribute("userLogin", login);
return msg;
}else{
msg.setMsg("你的账号在别处登录过,当前登录成功,另一个账号已强制下线");
//把当前cookie的值在数据库里面进行更新
login.setToken(currCookieValue);
userLoginMapper.updateUserLoginByUserAccount(login);
msg.setStatu(1);
login.setUserPassword(null);
//将当前用户的账号和姓名保存在session中、
request.getSession().setAttribute("userLogin", login);
return msg;
}
}
}
}
//cookie表示为空,则创建cookie
String newtoken=UUID.randomUUID().toString();
Cookie cookie=new Cookie("token", newtoken);
//设置cookie为主目录下面的路径,以便整个项目都可以获取cookie的信息来分辨
cookie.setPath(request.getContextPath()+"/");
//更新数据库里面的信息
login.setToken(newtoken);
userLoginMapper.updateUserLoginByUserAccount(login);
login.setUserPassword(null);
//将当前用户的账号和姓名保存在session中、
request.getSession().setAttribute("userLogin", login);
//将cookie添加到客户端
response.addCookie(cookie);
msg.setStatu(1);
return msg;
}
}
msg.setStatu(0);
msg.setMsg("账号或者密码错误,请重新登录");
return msg;
}
//判断用户是否已被注销,被注销则登陆失败
protected boolean isWriteOff(UserLogin currUser){
//数据库中的1为注销,0为可用
if(currUser!=null&&"1".equals(currUser.getWriteOff())){
return true;
}
return false;
}
还有就是值得注意的是,在cookie的使用操作过程中,在当前目录中创建的cookie,如果没有设置请求的路劲的有效cookie路劲,默认是当前的请求。比如:
当前创建的cookie的uri的访问地址为:login/user/
默认创建的cookie的默认在浏览器有效地址就是login/user/
在登录的时候,我们如果要实现一个拦截器来全部拦截某些需要经过登录验证的信息,我们如果访问的是/users/这个url,我们按照默认来处理的话,是不可能获取对应的cookie的值,得到的cookie的值是为空的,在自己操作的时候,确实是碰到的这个问题,导致自己蛮苦恼的,所以在根据自己的业务需要来使用cookie是蛮好的,cookie的路径的原则是:
在设置cookie的时候根据自己的需求范围相应的设置。cookie的使用path的时候,如果需要整个项目都需要这个cookie的话,设置path为当前的项目名就可以了,这样在项目中所有的项目都可以取到当前的cookie对象,也即是说cookie设置的范围大了,细分的路劲只要经过它,就会获取大范围的cookie,但在访问表示大范围的路劲访问的时候,是不会获取细粒度度分的cookie的对象的。这就是我对这个cookie路径(path)的理解。