当前位置: 首页 > 科技观察

刚才给女生科普了登录的两大技巧

时间:2023-03-13 17:02:34 科技观察

今天给大家聊一个比较基础的话题,就是实现登录的方法有哪些?适合刚入行的朋友。华山的Session聚雪Session我们称之为会话控制,是一种在服务器端保持会话状态的解决方案。通俗的说,当客户端访问服务器的时候,会在服务器上存储相应的信息,生成一个SessionID返回给客户端,客户端下次来的时候会带上这个SessionID,这样身份可以识别访客的身份。在请求中带上SessionID最常见的方式是通过cookie携带。cookie是客户端保存用户信息的一种机制。在浏览器环境下,请求会自动带上cookie信息,服务端也能拿到。会话ID。在后台实现登录逻辑时,首先获取HttpSession对象,然后通过setAttribute()设置登录用户信息,比如用户ID。在验证是否有登录时,使用getAttribute()获取对应的Session信息。如果没有获取到,证明没有登录或者session无效。对于Tomcat、Jetty等容器来说,Session是在服务器上开辟的一块内存空间,存储结构是Map。Tomcat的Session实现类似于StandardSession。分布式Session解决方案如果你的应用是部署在单节点上,这种场景下使用web容器实现的Session机制是没有问题的。一旦压力太大,需要多节点部署,Session就需要分布式支持。看下图,部署两台Tomcat时,通过Nginx进行负载均衡,第一个请求转发给Tomcat1,session信息存储在Tomcat1上。第二个请求转发给了Tomcat2,但是Tomcat2上没有之前的Session信息,这是多节点下Session出现的问题。Session复制Tomcat内置了session复制功能,就是你的Session是在Tomcat1中生成的,Tomcat1会将你的Session同步到Tomcat2中,这样当你的请求到达Tomcat2时,就可以知道你的身份信息。这种方案在其他框架中也经常看到,比如SpringCloud系统中的Eureka注册中心,也是采用复制的方式同步注册中心信息。TomcatSession复制相关配置,请参考官方文档:https://tomcat.apache.org/tomcat-8.0-doc/cluster-howto.htmlStickysessionStickysession指的是对同一个用户的请求,总是它只是转发给某个Tocmat实例,所以即使没有Session复制也不会有问题。如果一个节点挂了,访问就会失败。一种常见的方式是通过Hash转发IP。IP不是很可靠,因为它会改变。在Nginx中有一个nginx-sticky-module这个第三方模块用于添加一个始终转发到同一服务器的粘性cookie。nginx-sticky-module会在cookie中记录一个值,用来标识当前请求需要转发到哪个节点。如果第一次不可用,则先转发,然后写入cookie再响应客户端。后续请求会在cookie中找到对应的标识,然后转发给固定的节点。集中的会话存储和会话复制会占用服务器资源,影响性能。粘性会话存在单点故障风险。更好的分布式Session方式是集中存储。所谓集中存储就是将session信息存储在某个地方。像Tomcat这样的Web服务器本身不存储session信息,所以后端服务是无状态的,方便随时扩展。有很多实现方案。可以自己实现HttpSession做相应的存储读取逻辑,也可以使用开源方案。比如SpringSession是一个很好的开源方案,简单易用,支持多种存储方式,如Redis、Mysql等,如果对手写SpringSession原理感兴趣,也可以参考我之前的一套课程:http://cxytiandi.com/course/5ShaolinToken聚学Token认证是目前主流的认证方式之一,Token最大的优势是无状态的,不存储session信息。也就是说,通过Token,你可以知道当前访问的用户是谁,而不用去web容器的内存,也不需要从集中管理session的存储。Token的生成方式有很多种,你可以自己定义一个固定的格式,比如包含用户ID、用户名等信息。也可以使用目前主流的JWT方式。JWT(JSONWebToken)是一种基于JSON的开放标准,用于在Web应用程序环境中传输声明。JWT声明一般用于在身份提供者和服务提供者之间传递经过身份验证的用户身份信息,以便从资源服务器获取资源。例如,用户登录时,基本思路是用户向认证服务器提供用户名和密码,服务器验证用户提交信息的合法性;如果验证成功,它会生成并返回一个Token,然后请求用户带上这个Token,服务器可以识别这个请求的Identity信息。JWT由三部分组成,第一部分是头部(Header);第二部分是消息体(Payload);第三部分是签名(Signature)。JWT生成的Token格式为:token=encodeBase64(header)+'.'+encodeBase64(payload)+'.'+encodeBase64(signature)Header中的信息通常由两部分组成,Token的类型token和使用的Signature算法,比如下面的代码:{"alg":"HS256","typ":"JWT"}消息体可以携带一些应用需要的信息,比如用户ID,代码为如下:{"id":"1001","name":"yinjihuan"}签名用于判断消息在传输路径上是否被篡改,以保证数据的安全。格式如下:HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)通过这三部分构成我们的JSONWebToken。使用方法请参考Github:https://github.com/jwtk/jjwt如上图:请求到达Tomcat后,可以调用单独的Token服务生成Token,也可以封装Token生成逻辑打成jar包使用。需要注意的是,如果使用内嵌方式,Token对应的加密配置必须保持一致,否则会验证失败。Token的缺点是不能主动作废。比如我们使用Session的场景,用户注销后直接删除服务器上的Session信息。即使后面用同样的Session信息去请求,服务器也找不到。到相应的信息。Token是一个加密的字符串,里面包含了用户信息、加密算法和过期时间。如果过期时间设置的比较长,说明在过期时间之前就可以使用了。如果要实现注销功能,由于Token本身的过期时间是不可修改的,可以使用黑名单机制进行过滤。存储logoutToken,用它来匹配是否退出,然后拦截。作者简介:尹继焕,单纯的技术爱好者,《Spring Cloud 微服务-全栈技术与案例解析》、《Spring Cloud 微服务 入门 实战与进阶》的作者,公众号猩猩世界的创始人。