一周工作总结

session共享与跨域总结

前言

本周我一直在解决session共享问题,由于是第一次接触,所以用了这么久的时间,一路上学了很多,踩了很多坑,在此记录一下。

springboot整合redis管理session

学习springboot的过程中,知道了springboot整合了redis,于是顺便学习了redis。
利用redis存储session以达到session共享的目的。

成果

同一电脑的不同的服务器可以session共享。
不同的电脑的不同的服务器session无法共享。

原因与解决方法

服务器不在同一个域,所以使用nginx反向代理实现负载均衡,把不同服务器拉到同一个域。

nginx

刚接触nginx时不能理解负载均衡,于是配置ngnix后没有解决session共享问题。
第二天又认真学习了一下nginx,知道了nginx相当于一台代理服务器。
客户端统一访问一个域名,nginx监听这个域名并把请求转发给已在列表中配置过的服务器。
所以一个服务器崩了另一个服务器也能处理客户端的请求。
只有在服务器列表中的服务器的session才在一个域。

前后台分离时遇到的跨域问题

当前后台分离后,前台和后台各用一个端口,所以属于不同的域。
当前台向服务器发送请求时需要跨域,springboot的跨域只需要使用@CrossOrigin注解即可。

前后台分离时遇到的身份凭证的问题

session分为服务器的session和客户端的session。
session首先产生于服务器,如果客户端的请求设置了使用凭证(withCredentials),那么服务器会返回这个session,客户端也因此有了session。

问题

如果不设置使用身份凭证,会造成每次请求的session都不同的问题,但这时不管前台提交的是简单请求还是复杂请求,服务器都会成功响应。
如果使用了身份凭证,session便统一了,但同时又会有新的问题:服务器同意客户端的简单请求,却拒绝复杂请求之前的预检请求。
当提交的请求是复杂请求时,会先向服务器提交一个预检请求,预检请求的http方法是options类型。只有服务器通过了预检请求后,客户端才会发送真正的请求。
怎么才能解决预检请求的被拒绝的问题呢?要么前台把复杂请求改成简单请求,绕过这个坑,要么在后台设置相应的响应头。

跨域时后台响应头的设置

没有身份凭证时

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Headers", "*");

具有身份凭证时

response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");

踩过的坑

存session时开始存的是实体类对象,这么存在反序列化时会出现问题(找不到类、serialVersionUID不一致),如果存的是json文本就不会有问题。
使用tomcat-redis-session-manager时打包报错
前后台跨域时带身份凭证
设置响应头和@CrossOrigin不要同时使用,不然操作到了,效果没到,比如使用了@CrossOrigin后又设置允许携带身份凭证只需要在@CrossOrigin的参数列表进行设置,而不用设置响应头
通过nginx代理后,后台的Origin设置成nginx服务器的ip和端口,而不是前台的端口

参考文章

  1. session存入redis
  2. 负载均衡与粘滞会话
  3. nginx配置与使用
  4. 初识预请求
  5. http403原因
  6. CORS基础要点
  7. HTTP访问控制
  8. options请求方法后端配置
  9. 初识qs.stringify

你可能感兴趣的:(工作笔记)