1.前言

本文档描述现有BI项目的登录逻辑,涉及的服务有:api-gateway、bi-common-service、third-service和auth-service,共4个服务。

2.服务职能(在身份认证的逻辑中)

api-gateway 1.三个重要的过滤器
- CacheFilter
- ValidateSignFilter
- ValidateTokenFilter
bi-common-service 1.钉钉登录:DingTalkController下的ddLogin接口(/API120101)
2.账号密码登录:UserAuthController下的externalLogin接口(/API120301)
third-service 使用钉钉登录时,需要请求钉钉获取用户的unionid。不作细致的研究。
auth-service 发布用户登录后的令牌、验签

3.钉钉扫码登录流程详解

image.png

3.2请求参数解释

下图是扫描钉钉二维码登录后前端的请求参数,下面我对所有的参数做一个简单的个人理解的阐述。
image.png

3.2.1encrypt

这个请求参数是指定加密方式的,后端没有使用过这个参数。

3.2.2code

因为使用钉钉登录,需要获取钉钉的授权,钉钉使用的Oauth2的授权码模式,我们的前端将授权码,也就是是code获取到,并将授权码放入code这个字段中,后端会拿着code继续调用钉钉的接口获取access_token,从而获取用户的信息(钉钉id)。

3.2.3appid

bi项目有好多应用了,it工单、监察、ehr、全员营销,每一个项目都有一个应用信息,可以查看yurun_common数据库下的common_interface_signatue表。这里登录时使用通用的app_id。后端会对前端传来的appid进行正确性合法性的校验,具体逻辑后面讲具体类时说明
image.png

3.2.4timestamp

就是一个时间戳,作用就是标识了这个请求的发送时间。后端会使用此时间戳进行请求是否过期的校验。

3.2.5nonce

为每一次请求生成的唯一标识,后端只允许同一个请求发过来一次。

3.2.6sign

签名,这个字段配合appid字段使用的,后端根据appid获取appsecret,并使用appsecret对appid进行加密,加密的结果需要和前端传入的这个sign字段一致,才能校验通过。

3.3具体代码流程描述

image.png

3.4发布令牌具体逻辑

对于发布令牌,上图第⑥步的操作进行细致的说明。
image.png

4.登录后的逻辑

登录后,前端访问接口都会将access_token放入每次请求的头字段(Authorization)中。网关会通过token获取用户userid(jobno)和from信息(用户登录的位置信息),放入请求中,转发到相应的接口上。

4.1请求参数

登录成功后,前端在访问接口时,会在Header中添加一个Authorizatin字段,并将jwtResponse中的token字段值放入其中。其他的参数与登录时一样,具体到各自接口需要参数也会加入到其中。
image.png

4.2具体代码逻辑

image.png

5.令牌刷新逻辑

在登录后的JwtResponses对象中还有一个refresh_token字段,当前端调用刷新token的接口时,前端会将token和refresh_token一起传过来,并且authorization头字段中放入refresh_token.

5.1具体代码逻辑

image.png

5.2绿池的作用

1.不设置绿池时
①前端发送刷新token请求
②后端生成新的jwtResponse对象,并返回给前端。
③前端在下次请求时,带上新的token访问接口,一切正常的进行
2.可是,请求不会等待其他请求响应后才发送的,下面的场景就有问题了
①前端发送刷新token请求
②后端生成新的jwtResponse对象,清除了旧的token,将新的jwtResponse返回给前端
③前端还没接收到新的jwtResponse时,一次查询请求被用户触发,前端将旧的token放入请求头里
④后端检查token,发现这个token不存在,因为第②步时被清除了。返回未登录信息
3.因此在没有绿池时,会发生2所说的问题,加入绿池后就可以解决
①前端发送刷新token请求
②后端生成新的jwtResponse对象,清除了旧的token,并将旧token作为key,新jwtResponses作为value存在缓存中,最后将新的jwtResponse返回给前端
③前端还没接收到新的jwtResponse时,一次查询请求被用户触发,前端将旧的token放入请求头里
④后端检查token,发现这个token在绿池中,于是取出绿池中的新jwtResponses中的token使用
⑤后端正常返回接口的响应