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.钉钉扫码登录流程详解
3.2请求参数解释
下图是扫描钉钉二维码登录后前端的请求参数,下面我对所有的参数做一个简单的个人理解的阐述。
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进行正确性合法性的校验,具体逻辑后面讲具体类时说明
3.2.4timestamp
就是一个时间戳,作用就是标识了这个请求的发送时间。后端会使用此时间戳进行请求是否过期的校验。
3.2.5nonce
为每一次请求生成的唯一标识,后端只允许同一个请求发过来一次。
3.2.6sign
签名,这个字段配合appid字段使用的,后端根据appid获取appsecret,并使用appsecret对appid进行加密,加密的结果需要和前端传入的这个sign字段一致,才能校验通过。
3.3具体代码流程描述
3.4发布令牌具体逻辑
4.登录后的逻辑
登录后,前端访问接口都会将access_token放入每次请求的头字段(Authorization)中。网关会通过token获取用户userid(jobno)和from信息(用户登录的位置信息),放入请求中,转发到相应的接口上。
4.1请求参数
登录成功后,前端在访问接口时,会在Header中添加一个Authorizatin字段,并将jwtResponse中的token字段值放入其中。其他的参数与登录时一样,具体到各自接口需要参数也会加入到其中。
4.2具体代码逻辑
5.令牌刷新逻辑
在登录后的JwtResponses对象中还有一个refresh_token字段,当前端调用刷新token的接口时,前端会将token和refresh_token一起传过来,并且authorization头字段中放入refresh_token.
5.1具体代码逻辑
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使用
⑤后端正常返回接口的响应