Cookie、Session、Token
Cookie
简介:[Cookie]是一种小型文本文件,由服务器发送到用户的浏览器并保存在用户的计算机上。其主要作用是识别用户身份、跟踪用户活动、保存用户设置等。Cookie通常由名称、值、域名、路径、过期时间等字段组成,并且可以存储在用户的硬盘或内存中。
Cookie的定义和作用
Cookie是一种由服务器发送到用户浏览器并保存在用户计算机上的小型文本文件。它主要用于识别用户身份、跟踪用户活动、保存用户设置等。例如,当用户登录一个网站时,服务器会生成一个包含会话ID的Cookie并发送给浏览器,浏览器将这个Cookie保存在本地。此后,每次用户发送请求时,浏览器都会自动将这个Cookie发送给服务器,服务器通过会话ID识别用户身份,从而保持用户的登录状态。
Cookie的组成和类型
Cookie通常由以下几个部分组成:
- - 名称(Name):Cookie的名称,一旦创建,名称不可更改。
- - 值(Value):存储的具体数据。
- - 路径(Path):Cookie的使用路径,通常以“/”表示根路径。
- - 过期时间(Expires/Max-Age):Cookie的有效时间,单位为秒。默认情况下,浏览器关闭后Cookie即失效。
- - 域名(Domain):可访问该Cookie的域名。
- - 安全标志(Secure):表示Cookie是否仅通过安全协议传输。
根据用途,Cookie可以分为以下几种类型:
- - 会话Cookie(Session Cookies):在浏览器关闭后即失效。
- - 持久Cookie(Persistent Cookies):存储在用户的硬盘上,直到过期或被删除。
Cookie的应用场景和安全性问题
1. 会话管理:用于保持用户的登录状态,通过会话ID识别用户身份。
2. 个性化设置:保存用户的个性化设置,如主题、语言、字体大小等。
3. 购物车功能:在电子商务网站中保存购物车信息。
4. 跟踪用户行为:记录用户在网站上的活动,如访问页面、停留时间、点击链接等。
5. 权限验证:作为用户的通行证,验证用户身份。
安全性问题
由于Cookie在HTTP请求中以明文传递,存在安全隐患。为了增强安全性,可以采用以下措施:
- - 加密存储:对敏感信息进行加密处理。
- - 使用安全协议:仅通过安全协议传输Cookie。
- - 设置Secure标志:确保Cookie仅通过安全协议传输
Session
[Session]是一种在服务器端存储与特定用户或客户端相关信息的机制。它通过服务器端的一个对象来存储用户的数据,每个Session对象都有一个唯一的ID,这个ID通过[Cookie]的形式发送给客户端。客户端在每次访问时只需将存储有ID的Cookie发回,服务器即可通过这个ID识别客户端并提供相应的个性化服务和数据。
Session的基本概念和作用
Session主要用于在网络应用中维持客户端与服务器之间的持久性交互,确保在多个请求之间能够维护客户端的状态信息。它通过会话标识符(Session ID)来唯一标识一个会话,使得在用户会话期间,可以在不同的请求之间共享状态信息。Session常用于存储用户的登录信息、购物车内容、用户偏好设置等,提供个性化体验并方便管理用户数据。
Session与[Cookie]的关系
Session和Cookie是一对互补的技术。当用户第一次访问网站时,服务器会创建一个Session对象并生成一个唯一的Session ID,然后将这个ID以Cookie的形式发送给客户端。客户端在后续的请求中携带这个Cookie,服务器通过Cookie中的Session ID识别用户,从而实现用户状态的维持和个性化服务的提供。虽然Session数据存储在服务器端,但需要通过Cookie来传递Session ID,因此在不支持Cookie的浏览器中,Session将无法正常工作。
Session的应用场景和优缺点
优点:
- - 个性化体验:提供个性化的服务,如根据用户的偏好展示不同的内容。
- - 方便管理:集中存储用户数据,便于管理和查询。
缺点:
- - 性能影响:可能会增加服务器的负担,特别是在高并发情况下。
- - 安全性问题:如果Session ID被截获,可能会导致用户信息泄露或会话劫持。
通过理解Session的基本概念、工作原理以及与Cookie的关系,可以更好地利用这一技术来提升网络应用的用户体验和数据管理效率
JWT
官网:[JSON Web Token Introduction - jwt.io](https://jwt.io/introduction/)
[JWT](JSON Web Token)是一种基于JSON格式的开放标准,用于在网络应用环境间传递声明,特别适用于身份验证和授权。 JWT的设计目的是为了在网络应用环境间安全地传输信息,通常用于[分布式系统]中的身份验证和授权场景,特别是在[单点登录](SSO)和跨域身份验证中。
JWT的基本概念和特点
JWT具有以下几个特点:
- - 轻量级:JWT是一个紧凑且自包含的数据格式,可以通过HTTP头或URL参数进行传输。
- - 自包含:JWT包含了足够的信息,使得客户端可以判断是否信任该令牌,而不需要查询服务器。
- - 可扩展:基于JSON格式,可以自定义Payload中的属性来适应各种业务需求。
- - 安全:使用签名来验证发送方和接收方之间的身份,确保消息的机密性和完整性。
JWT的结构
JWT由三个部分组成:头部(Header)、载荷(Payload)和签名(Signature):
1. 头部:包含令牌的类型(JWT)和使用的加密算法(如HS256)。
是一个JSON对象,用来描述JWT的元数据
```json{"alg": "HS256","typ": "JWT"}```
alg属性表示签名的算法(algorithm),默认是 HMAC SHA256 (写成 HS256) ;typ属性表示这个令牌(token)的类型(type),JWT令牌统一写为JWT。 最后,将上面的JSON对象使用Base64URL算法转成字符串。
2. 载荷:包含需要传递的数据,如用户身份信息、角色、权限等。
是一个JSON对象,用来存放实际需要传递的数据,JWT规定了7个官方字段
- ① iss (issuer):签发人
- ②exp (expiration time):过期时间
- ③sub (subject):主题
- ④nbf (Not Before):生效时间
- ⑤iat (lssued At):签发时间
- ⑥jti (JWT ID):编号
- ⑦aud (audience):受众
3.签名:基于头部和载荷的信息,使用秘钥生成的签名,用于验证令牌的真实性和完整性。
Signature部分是对前两部分的签名,防止数据篡改。 首先,需要指定一个==密钥 (secret)==。这个密钥只有服务器才知道,不能泄露给用户。然后,使用Header里面 指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。 HMACSHA256( base64UrlEncode(header) + ".”"+base64UrlEncode(payload), secret) 算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就 可以返回给用户。
JWT的使用场景和优势
JWT广泛应用于[RESTful API]中,因为它不需要维护任何状态信息。使用JWT可以解决传统[Session]机制在分布式系统中的问题,如session共享和扩展性问题。JWT通过在用户登录时生成一个令牌,客户端保存这个令牌并在每次请求时携带,服务器通过验证令牌来认证用户,从而简化了认证过程并提高了系统的可扩展性
JWT的使用方式
客户端收到服务器返回的JWT,可以储存在Cookie里面,也可以储存在 localStorage。SessionStorage 此后,客户端每次与服务器通信,都要带上这个JWT。你可以把它放在Cookie里面自动发送,但是这样不能跨域,所以更好的做法是放在HTTP请求的头信息Authorization字段里面
引入jar:
```xml
<!--引入jwt的依赖--><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version></dependency>
```
创建jwt的工具类:
```java
public class JWTUtil {private static String key="1suo";//通过jwt创建token令牌public static String createToken(Map<String,Object> map){Map<String,Object> head=new HashMap<>();head.put("alg","HS256");head.put("typ","JWT");Date date=new Date();//发布日期Calendar instance = Calendar.getInstance();//获取当前时间instance.set(Calendar.SECOND,7200);//在当前时间的基础上添加7200秒Date time = instance.getTime();String token = JWT.create().withHeader(head) //设置头.withIssuedAt(date) //设置发布日期.withExpiresAt(time) //设置过期时间.withClaim("userinfo", map) //设置个人信息.sign(Algorithm.HMAC256(key));//签名return token;}//校验tokenpublic static boolean verify(String token){Verification require = JWT.require(Algorithm.HMAC256(key));try {require.build().verify(token);return true;}catch (Exception e){System.out.println("token错误");return false;}}//根据token获取自定义的信息public static Map<String,Object> getInfo(String token,String mykey){JWTVerifier build = JWT.require(Algorithm.HMAC256(key)).build();Claim claim = build.verify(token).getClaim(mykey);return claim.asMap();}
}
```