1、MD5&盐值&BCrypt
MD5 (Message Digest algorithm 5,信息摘要算法)
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、强抗碰撞:想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。
5、不可逆
加盐:
1、通过生成随机数与MD5生成字符串进行组合
2、数据库同时存储MD5值与salt值。验证正确性时使用salt进行MD5
1 2 3
| + Spring的加密 + 自动加盐 + match匹配(与encode匹配)
|
2、分布式session共享
问题:
不同服务session不共享
同一服务session不同步
session原理
分布式session解决方案
1、session复制
Session复制(tomcat之间同步)
1 2 3 4 5 6
| + 优点: + web-server(Tomcat)原生支持,只需要修改配置文件 + 缺点: + session同步需要数据传输,占用大量网络带宽,降低了服务器群的业务处理能力 + 任意一台web-server保存的数据都是所有web-server的session总和,受到内存限制无法水平扩展更多的web-server + 大型分布式集群情况下,由于所有web-server都全量保存数据,所以此方案不可取。
|
2、客户端存储
放到cookie中
1 2 3 4 5 6 7 8
| + 优点 + 服务器不需存储session,用户保存自己的session信息到cookie中。 + 节省服务端资源 + 缺点 + 都是缺点,这只是一种思路。 + 每次http请求,携带用户在cookie中的完整信息,浪费网络带宽 + session数据放在cookie中,cookie有长度限制4K,不能保存大量信息 + session数据放在cookie中,存在泄漏、篡改、窃取等安全隐患
|
3、hash一致性
Hash一致性(修改负载均衡)
+ 服务器闪断会丢失
+ 服务器数量变化重新hash,部分会丢失
1 2 3 4 5 6 7 8 9 10
| + 优点: + 只需要改nginx配置,不需要修改应用代码 负载均衡,只要hash属性的值分布是均匀的,多台web-server的负载是均衡的 + 可以支持web-server水平扩展(session同步法是不行的,受内存限制) 缺点 + session还是存在web-server中的,所以web-server重 启可能导致部分session丢失,影响业务,如部分用户 需要重新登录 + 如果web-server水平扩展,rehash后session重新分布, 也会有一部分用户路由不到正确的session + 但是以上缺点问题也不是很大,因为session本来都是有有
|
4、统一存储
1 2 3 4 5 6 7
| + 优点: + 没有安全隐患 + 可以水平扩展,数据库/缓存水平切分即可 + web-server重启或者扩容都不会有 session丢失 + 不足 + 增加了一次网络调用,并且需要修改应 用代码;如将所有的getSession方法替换为从Redis查数据的方式。redis获取数 据比内存慢很多 + 上面缺点可以用SpringSession完美解决
|
5、扩大cookie作用域
解决子域共享问题
问题:多域名
SpringSession
配置类:json编码、cooki子域问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Configuration public class GulimallSessionConfig { @Bean public CookieSerializer cookieSerializer() { DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); cookieSerializer.setDomainName("gulimall.com"); cookieSerializer.setCookieName("GULISESSION"); return cookieSerializer; }
@Bean public RedisSerializer<Object> springSessionDefaultRedisSerializer() { return new GenericJackson2JsonRedisSerializer(); } }
|
原理:装饰者模式
狸猫换太子
@EnableRedisHttpSession 导入 RedisHttpSessionConfiguration 配置
1、给容器中添加了一个组件 RedisOperationsSessionRepository:Redis操作session,session的增删改查封装类;
2、继承 SpringHttpSessionConfiguration 初始化了一个 SessionRepositoryFilter:session 存储过滤器;每个请求过来都必须经过 Filter 组件;创建的时候,自动从容器中获取到了 SessionRepository;
SessionRepositoryFilter:
- 将原生的 HttpServletRequest Response 包装成 SessionRepositoryRequestWrapper ResponseWrapper;包装后的对象应用到了后面整个执行链;
- 以后获取 request.getSession(); 都会调用 wrappedRequesr.getSession(); 从SessionRepository获取;
3、装饰者模式
1 2 3 4 5 6 7 8 9 10 11 12
| protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository); SessionRepositoryFilter<S>.SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryFilter.SessionRepositoryRequestWrapper(request, response); SessionRepositoryFilter.SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryFilter.SessionRepositoryResponseWrapper(wrappedRequest, response);
try { filterChain.doFilter(wrappedRequest, wrappedResponse); } finally { wrappedRequest.commitSession(); }
}
|
3、sso单点登录
跨域名单点登录简单实现:
1、服务端:未登录跳转认证中心(附带参数保存原地址)
2、认证中心:登录成功本地保存cookie(sso_token)
3、认证中心:保存登录用户登录状态到redis中
4、认证中心:重定向url中附带token跳转回原页面
5、服务端:根据token查询redis获取用户信息保存session
6、其他服务端:未登录跳转到认证中心,直接登录成功返回
服务端:根据有无session判断是否登录
认证中心:根据有无sso_token判断是否登录
可实现:filter、jwt、springsecurity
4、ThreadLocal同一个线程共享数据
1 2 3 4 5 6 7
| public static ThreadLocal<UserInfoTo> toThreadLocal = new ThreadLocal<>();
toThreadLocal.set(userInfoTo);
UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
|