1.JWT

1.1 JWT是什么,为什么要使用它

通常情况下,如果直接把API接口暴露出去风险是很大的,所以一般需要对API划分出一定的权限级别,然后做一个用户的鉴权,依据鉴权结构给予用户对应的API
在互联网服务器中的一般认证流程:

1.用户向服务器发送用户名和密码。

2.服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色,登录时间等等。

3.服务器向用户返回一个session_id,写入用户的Cookie。

4.用户随后的每一次请求,都会通过Cookie,将session_id传回服务器。

5.服务器收到session_id,找到前期保存的数据,由此得知用户的身份。

这种模式的问题在于:扩展性不好,在集群环境下,就得考虑session共享问题,所以这个时候JWT就派上用场了,即服务器索性不保存session数据了,所有数据都保存在客户端,每次请求都发回服务器验证。

1.2 JWT的结构

JWT包含了使用.分隔的三部分:

  • Header 头部

  • Payload 负载

  • Signature 签名

JWTString=Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

 Header

JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

 有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择

iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT

 这些预定义的字段并不要求强制使用。除以上默认字段外,我们还可以自定义私有字段,一般会把包含用户信息的数据放到payload中,如下例:

{
  "sub": "1234567890",
  "name": "Helen",
  "admin": true
}

Signature

签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名

HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

1.3 JWT的工作流程

1.用户导航到登录页,输入用户名、密码,进行登录
2.服务器验证登录鉴权,如果用户合法,根据用户的信息和服务器的规则生成JWT Token
3.服务器将该token以json形式返回(不一定要json形式,这里说的是一种常见的做法)
4.用户得到token,存在localStorage、cookie或其它数据存储形式中。
5.以后用户请求/protected中的API时,在请求的header中加入 Authorization: Bearer xxxx(token)。此处注意token之前有一个7字符长度的 Bearer
6.服务器端对此token进行检验,如果合法就解析其中内容,根据其拥有的权限和自己的业务逻辑给出对应的响应结果。
7.用户取得结果

1.4 JWT的优点

支持跨域访问:cookie是无法跨域的,而token由于没有用到cookie(前提是将token放到请求头中),所以跨域后不会存在信息丢失问题
无状态:token机制在服务端不需要存储session信息,因为token自身包含了所有登录用户的信息,所以可以减轻服务端压力
更适用CDN:可以通过内容分发网络请求服务端的所有资料
更适用于移动端:当客户端是非浏览器平台时,cookie是不被支持的,此时采用token认证方式会简单很多
无需考虑CSRF:由于不再依赖cookie,所以采用token认证方式不会发生CSRF,所以也就无需考虑CSRF的防御

1.4 JWT弊端

JWT其实是只负责生成token,并不负责管理token,所以当系统登出 的时候,JWT是没有办法对token进行清除操作的,一般使用JWT的,他们采取的策略是:让此token验证不过,有如下方案:

1.若使用了redis,登出的时候将此token放入黑名单

2.若不使用token,在登出的时候修改生成token的用户字段,则下次请求携带的token一定是验证不过的

2.Spring Security

Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架。

一般来说,Web应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分,用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户授权指的是验证某个用户是否有权限执行某个操作。

springsecurity底层实现为一条过滤器链,就是用户请求进来,判断有没有请求的权限,抛出异常,重定向跳转。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐