HTTP Basic Auth就是每次请求都会提供用户的用户名和密码 , 也就是说它是使用最简单的认证方式,只需要提供密码即可。
由于它每次都需要将密码暴露给第三方,因此他是不安全的,现在使用也越来越少。
Cookie认证机制也就是每次请求认证都会在服务端创建一个session对象,同时在浏览器端创建一个Cookie对象。 通过客户端上带的Cooke来和服务器端的session对象匹配来实现验证。
它属于一个开放的授权标准,允许用户让第三方应用访问该用户在某一web服务上存储私密资源,且不用将用户名和密码提供给第三方。 这样说可能不明白,呢你们想一下在使用app时,有没有用到微信登录、qq登录等第三方登录。
Oauth相当于提供给用户一个令牌,来去访问。而不是需要用户名和密码去访问。
类似于这种,就相当于授予令牌 来直接去用第三方账户登录:
请求流程:(图片来源于网络)
jwt (JSON Web Token) 属于一个规范,它定义了一种简洁的、自身包含协议的格式,用于在通信双方传递json对象。适合使用在分布式站点的单点登录(SSO)场景。
官网:https://jwt.io/
JWT优点:
缺点: 字符串过长,占用存储空间过大。
JWT由三部分组成,分别是:头部,载荷和签名。 JWT实际上是一个字符串,以 . 来分割开。
alg:采用的算法; typ:类型
这里我们对头部的json字符串进行BASE64编码 ,eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Base64是可以基于64个可打印字符来表示二进制的表示方法。 其中每六个比特为一个单元。 JDK也为我们提供了相关的方法可以去完成BASE64的编码和解码。
它包含了三种声明方式:
sub:jwt所面向的用户
iat:jwt的签发时间
无论是哪种方式,都不建议存放隐私信息,因为这部分是明文可以进行解密的。
这个签证信息由三部分组成,header、payload、secret(保密)
其中:
secret:存放在服务器端,它是用来进行jwt的签发和jwt的验证,也就相当于密钥。 因此这个不能泄露,如果客户端知道了,也就意味着客户端可以自己签发jwt。
有兴趣的同学可以去官网试一下,每一个secret不一样对应的token也不相同。
导入相关依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
创建token:
public void testCreateToken(){
// 创建Jwtbuilder对象
JwtBuilder jwtBuilder = Jwts.builder()
// 声明标识:{jwt:8888}
.setId("1111")
// 主体,用户 {sub:1234567890}
.setSubject("1234567890")
// 创建日期 {ita:"xxxx"}
.setIssuedAt(new Date())
// 采用编码算法:hs256
.signWith(SignatureAlgorithm.HS256,"xxxx");
获取token:
前面介绍过 ,JWT由三部分组成,是一个字符串且由 .
进行分割。 因此这里我们直接进行字符串分割,然后调用Base64Codec.BASE64
进行解密即可。
//获取token
String token = jwtBuilder.compact();
System.out.println(token);
String[] split = token.split("\\.");
System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
// 无法解密secret
System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
}
运行后我们可以发现,secret也就是签名部分是乱码。 其他部分正常显示。 能进行编码,当然也能解析
解析token(这里使用上面加密出的token):
public void ParseToken(){
String token = "eeyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxMTExIiwic3ViIjoiMTIzNDU2Nzg5MCIsImlhdCI6MTY0ODk1NzM1MH0.VzT6kEyf71MtUyUdy1lUMCys5hUCJPWy_782A19OX3Y";
// 解析token获取负载中的声明对象
Claims claims = Jwts.parser()
.setSigningKey("xxxx")
.parseClaimsJws(token)
.getBody();
System.out.println("id : "+claims.getId());
System.out.println("subject: "+ claims.getSubject());
System.out.println("issueAt : "+claims.getIssuedAt());
}
解析结果: