用户登录时,服务器创建一个 token值,并设置一个cookie保存至浏览器
User user = new User();
//使用token辨认用户
String token = UUID.randomUUID().toString();
user.setToken(token);
user.setName(gitHubUser.getLogin());
user.setAccountId(String.valueOf(gitHubUser.getId()));
user.setAvatarUrl(gitHubUser.getAvatarUrl());
userService.createOrUpdaete(user);
//登录成功,将登录的用户保存至session
request.getSession().setAttribute("user", user);
//将登录成功地用户的token值保存至浏览器cookies里面
Cookie cookie = new Cookie("token", token);
cookie.setMaxAge(30 * 24 * 3600);
response.addCookie(cookie);
//跳转至首页
ModelAndView modelAndView = new ModelAndView("redirect:index");
redirectAttributes.addFlashAttribute("msg", "登录成功");
当用户关闭浏览器,再次打开时,cookie记录了token值,
用户就不需要登录
了,打开界面时,请求会查找本地cookie里面的token值,与服务器端user的token值进行匹配,匹配成功就加入session
那么当前会话就可以一直保持
package life.majiang.community.interceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import life.majiang.community.mapper.UserMapper;
import life.majiang.community.model.User;
import life.majiang.community.model.UserExample;
import life.majiang.community.service.NotificationService;
/**
* 项目名: community
* 包名: life.majiang.community.interceptor
* 文件名 SessionInterceptor
* 创建者
* 创建时间: 2020/3/20 4:47 PM
* 描述 如果SessionInterceptor 没有@Service注解,userMapper就不会工作
*/
@Service
public class SessionInterceptor implements HandlerInterceptor {
@Autowired
private UserMapper userMapper;
@Autowired
private NotificationService notificationService;
/**
* 每次请求都查询用户是否登录
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//先判断,当前用户是否已经登录,已经登录就放行
//session中没有user值,然后再根据cookie里面的token值与用户进行匹配
User user = (User) request.getSession().getAttribute("user");
if (user == null) return true;
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
String token = cookie.getValue();
// User user = userMapper.findByToken(token);
//根据token查找登录的用户
//如果查找到,就保存当前登录的用户至session
UserExample userExample = new UserExample();
userExample.createCriteria().andTokenEqualTo(token);
List<User> users = userMapper.selectByExample(userExample);
if (users.size() != 0) {
request.getSession().setAttribute("user", users.get(0));
/**
* 更新头部,通知数
*/
Long unreadCount = notificationService.unreadCount(users.get(0).getId());
request.getSession().setAttribute("unreadNotificationCount", unreadCount);
}
break;
}
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
}
我觉得拦截器,可以先查询session中是否存在user,如果存在则放行,如果不存在就查找本地cookie里面的token值和user进行匹配,如果用户登录后还需要匹配用户的token值或者一些界面不需要用户登录依旧和user进行匹配,效率太慢了
以后需要登录后的用户获取权限时,就可以这样子判断
@PostMapping("/publish")
public String doPublish(@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam("tag") String tag,
@RequestParam("id") Long id,
HttpServletRequest request,
Model model)
----------------------------------------------------------------------------
User user = (User) request.getSession().getAttribute("user");
if (user == null || user.getName().length() < 1) {
model.addAttribute("error", "用户未登录");
System.out.println("用户未登录");
return "publish";
}
----------------------------------------------------------------------------
@GetMapping("/notification/{id}")
public String notification(@PathVariable(name = "id") Long id,
Model model,
HttpServletRequest request)
----------------------------------------------------------------------------
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
return "redirect:/";
}