项目技术点

本文介绍了Redis结合Lua脚本实现接口限流的机制,包括定义切入点接口、切面类以及Lua脚本的使用。同时,详细阐述了JWT(JSON Web Token)的原理和构成,分析了其相较于传统session+cookie的优势,以及JWT的签发和续期流程。
摘要由CSDN通过智能技术生成

1、Redis+Lua脚本限流

1.1.定义切入点接口(小旗子),添加四个属性并赋初值,后续用到。

1.2.定义切面类,使用前置通知实现IP限流,其中

  1. MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature()----》获得修饰符+ 包名+组件名(类名) +方法名
  2. Method method = methodSignature.getMethod()----》获取方法名
  3. PugRateLimiter annotation = method.getAnnotation(PugRateLimiter.class)----》通过方法名上面的“小旗子”类,获取注解携带的限流参数
  4. Integer limit = annotation.limit()----》获取限制次数
    Integer timeout = annotation.timeout()----》获取限制时间
  5. ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes() ----》获取请求属性
  6. HttpServletRequest request = requestAttributes.getRequest()----》获取请求对象
  7. String methodNameKey = getRateLimiterKey(annotation, joinPoint, request)----》获取redis的key
  8. String userIp = IpUtils.getIpAddr(request)----》获取请求IP
  9. Boolean acquired = stringRedisTemplate.execute(ipLimitLua, Lists.newArrayList(methodNameKey), limit.toString(), timeout.toString())----》请求lua脚本实现限流,根据返回值进一步进行限流返回操作

方法 getRateLimiterKey ---- 获取Redis 的 key,最终Key返回值为:IP-声明的class对象名-方法名

stringRedisTemplate.execute(ipLimitLua, Lists.newArrayList(methodNameKey), limit.toString(), timeout.toString()) 方法,真正实现限流的方法

ipLimiLua----》用来读取lua脚本,序列化为java可以操作的语言

 stringRedisTemplate.execute方法:用来执行lua脚本的,返回的是lua脚本执行之后的返回值。

2、JWT 实现免登录

2.1 JWT 介绍

jwt是为了解决传统session+cookie的登录校验的缺点。

传统的session+cookies的方法,session存储在服务端,这样客户端每次发起请求的时候只能请求同一个服务器,且将校验数据存储在服务器端会占用大量内存,不利于维护和扩展。而且cookie一旦被拦截,则用户很容易遭受跨站请求伪造的攻击。

而基于jwt  token的鉴权机制,则是将认证信息(token)保存在客户端,服务端只需要保存用于加解密的secret(盐/密钥),每次客户端访问时,将首次访问服务端派发的token携带在请求头中,这样服务端拿到token,然后利用服务端存储的secret来进行解密,从而鉴权。服务器需要支持CORS(跨域资源共享)策略,以便于服务器密钥共享。

2.2 JWT组成

JWT 由三部分构成,分别是头部(header)、载荷(payload,类似于飞机上承载的物品)、签证(signature)。将这三部分用“ . ”连接起来,就构成了JWT字符串。

例如:

<pre>eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySWQiOjEyMywiVXNlck5hbWUiOiJhZG1pbiJ9.Qjw1epD5P6p4Yy2yju3-fkq28PddznqRj3ESfALQy_U</pre>

header

header主要包含两部分信息:

  • 声明类型,这里是jwt
  • 声明加密的算法,通常直接使用HMAC SHA256

完整的头部如:<pre>{ 'typ':'JWT', 'alg':'HS256' }</pre> ,然后经过based64加密(该加密是可以对称解密的),构成JWT第一部分:<pre>eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9</pre>

payload

载荷是用来存放有效信息的地方,它主要包含三部分:

  • 标准中注册的声明

    1.  iss:jwt签发者

    2. sub:jwt所面向的用户

    3. aud:接收jwt的一方

    4. exp:jwt的过期时间,这个过期时间必须大于签发时间

    5. nbf:定义在什么时间之前,该jwt都是不可用的

    6. iat:jwt的签发时间

    7. jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击 

  • 公共的声明

       公共的声明可以添加任何的信息,一般添加用户的相关信息或其它业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密 。

  • 私有的声明

      私有的声明是提供者和消费者功能定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为名文信息。

payload:<pre>{ "sub": "1234567890", "name": "John Doe", "admin": true }</pre>,经过based64加密:<pre>eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9</pre>

Signature

签证是JWT的第三个部分,这个部分需要base64加密后的header和base64加密后的payload使用“.”连接组成字符串,然后用header中声明的加密方式,然后进行加secret加密。

如:

<pre>var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload); var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ</pre>

最终的JWT,就是由这三部分用“ . " 连接起来组成一个完整字符串:

<pre>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ</pre>

jwt 优点:

  • 因为json的通用性,所以JWT是可以跨语言支持的,像C#,JavaScript,NodeJS,PHP等许多语言都可以使用

  • 因为由了payload部分,所以JWT可以在自身存储一些其它业务逻辑所必要的非敏感信息

  • 便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的

  • 它不需要在服务端保存会话信息,所以它易于应用的扩展

注意点:

  • 不应该在jwt的payload部分存储敏感信息,因为该部分是客户端可解密的部分

  • 保护好secret私钥。该私钥非常重要

项目分析:

签发token过程:登录接口根据传入用户名来判断是否访问过,没有则派发token

 

 

 token续期过程:

token

一般是在请求头里加入Authorization,并加上Bearer标注:

<pre>fetch('api/user/1', {
headers: { 'Authorization': 'Bearer ' + token
}
})</pre>

首先判断请求头中是否有token,token需要前缀Bearer

 若请求头带有token则判断是否过期。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值