20. cache、cookie、session、token 区别
时间: 2024-01-30 13:01:33 浏览: 267
Cache是指缓存,可以将常用的数据或文件保存在本地,加快加载速度。Cookie是指网站为了辨别用户身份而存储在用户本地终端上的数据。Session是指用户与服务器之间的会话信息,可以在服务端存储用户的状态信息。Token是指一种用户访问授权方式,用户在登录后,系统返回Token,用户在访问需要授权的接口时需要携带Token来验证身份。
相关问题
解释这段代码@Component public class AuthorizationInterceptor implements HandlerInterceptor { public static final String LOGIN_TOKEN_KEY = "Token"; @Autowired private TokenService tokenService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //支持跨域请求 response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization"); response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); // 跨域时会首先发送一个OPTIONS请求,这里我们给OPTIONS请求直接返回正常状态 if (request.getMethod().equals(RequestMethod.OPTIONS.name())) { response.setStatus(HttpStatus.OK.value()); return false; } IgnoreAuth annotation; if (handler instanceof HandlerMethod) { annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class); } else { return true; } //从header中获取token String token = request.getHeader(LOGIN_TOKEN_KEY); /** * 不需要验证权限的方法直接放过 */ if(annotation!=null) { return true; } TokenEntity tokenEntity = null; if(StringUtils.isNotBlank(token)) { tokenEntity = tokenService.getTokenEntity(token); } if(tokenEntity != null) { request.getSession().setAttribute("userId", tokenEntity.getUserid()); request.getSession().setAttribute("role", tokenEntity.getRole()); request.getSession().setAttribute("tableName", tokenEntity.getTablename()); request.getSession().setAttribute("username", tokenEntity.getUsername()); return true; } PrintWriter writer = null; response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); try { writer = response.getWriter(); writer.print(JSONObject.toJSONString(R.error(401, "请先登录"))); } finally { if(writer != null){ writer.close(); } } // throw new EIException("请先登录", 401); return false; }
这段代码是一个拦截器,用于拦截请求并进行权限验证。它会在每个请求被处理之前执行,首先设置一些跨域请求的头信息,然后判断该请求是否为OPTIONS请求,如果是,则直接返回正常状态。如果不是OPTIONS请求,则获取请求方法是否包含IgnoreAuth注解,如果包含,则直接放过不需要验证权限的方法。如果不包含IgnoreAuth注解,则从请求头中获取token,并通过TokenService验证token的有效性。如果token有效,则将用户信息保存到session中,否则返回401未授权错误。
return func(c *gin.Context) { origin := c.Request.Header.Get("origin") //请求头部 if len(origin) == 0 { origin = c.Request.Header.Get("Origin") } //接收客户端发送的origin (重要!) c.Writer.Header().Set("Access-Control-Allow-Origin", origin) //允许客户端传递校验信息比如 cookie (重要) c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") //服务器支持的所有跨域请求的方法 c.Writer.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE, UPDATE") c.Writer.Header().Set("Content-Type", "application/json; charset=utf-8") // 设置预验请求有效期为 86400 秒 c.Writer.Header().Set("Access-Control-Max-Age", "86400") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() }
使用 CSRF token 可以比较安全地传递校验信息。CSRF token 是一种防止跨站请求伪造攻击的技术,其原理是在服务器端生成一个随机字符串(token),并将其放入登录用户的 session 中,然后将该 token 发送给客户端,客户端每次请求时需要将该 token 一并发送给服务器,服务器验证该 token 是否与用户 session 中的一致,从而确定该请求是否有效。这样即使攻击者在客户端伪造请求,由于没有正确的 CSRF token,服务器会拒绝该请求。
阅读全文