与第三方系统交互-令牌AccessToken机制
传统Web应用中,前后端并不分离,用户登录后在服务端会话中保存用户的AccessToken并为用户在服务器端开辟存储与资源空间(就像一个小房间一样,而AccessToken就像房间的钥匙),并把此AccessToken发送给前端浏览器,浏览器通过Cookie的方式保存起来,浏览器每次请求均携带此AccessToken,请求到达后服务端根据此AccessToken来识别具体的用户用户空间,并访问用户的存储和权限等资源。
平台系统对外提供API时,目前主流的做法是采用RESTful风格的接口服务,对所有来访的端均一视同仁,无论是App端、PC端、微信小程序端、硬件端还是前后端分离的前端,这样开发一套API就可以服务所有的端用户。
在前后端分离的架构模型中,是没有“自动”化的机制完成AccessToken的回传与检验的,这部分工作要由我们自己手动来完成。
端是对用户GUI界面的统称,此处意指APP、微小小程序、微信公众号、PC、第三方系统、智能设备等,下同。
第三方访问凭据
平台为第三方维护基本信息,其中包含了两个重要的数据字段AppId和AppSecret,其中AppId和平台本地用户的登录名是起相同的作用,它用来唯一的标识一个第三方合作单位;而AppSecret和平台本地用户的登录密码是起相同的作用,它是一个密钥或者叫密码。
用户表.png
合作机构表.png
登录与令牌
如果是平台本地用户,用户在端界面输入登录名或密码及验证码后,提交至平台服务端,经过重重验证机制后获取一个AccessToken和过期时间保存在本地,调用接口时传入AccessToken即可。
如果是第三方合作平台,通过调用指定的接口并传入AppId和AppSecret,直接换取一个AccessToken令牌和过期时间保存在本地,调用接口时传入AccessToken即可。
服务端生成用户的访问令牌(可以是一个GUID),并在库中查询出该用户的权限列表信息,然后将用户信息、登录时间、过期时间、权限列表有组织的入库(防止服务器断电或异常造成的令牌信息丢失),然后在缓存中也保存一份儿(键名就是生成的真实的Token)。
登录.png
用户与服务器正常的交互,仅访问缓存中令牌信息;服务器启动时,扫描库中未过期的令牌信息并读入缓存,同时将过期的令牌信息清除掉;订阅捕获缓存失效移除事件,将库中对应的令牌清除掉;设立定时器,定期扫描库中的令牌信息,移除过期的令牌。
定时器.png
令牌安全性
令牌是开放的,有可能被恶意用户伪造篡改,从而访问到其他用户的资源信息(虽然这种机率非常小),因此必须引入签名机制。
服务器端生成令牌后,将令牌通过服务端的私钥进行签名,然后组合出来一个复合令牌,令牌的格式为:真实令牌|过期时间|签名串,发送给端的令牌其实是这个复合令牌。
令牌安全.png
令牌检验
定义一个过滤器,统一对令牌进行拦截处理,在此过滤器中主要做两件事情:1.验证令牌是否存在,不存在就直接返回错误信息;2.验证令牌是否过期,如果过期就移除缓存和库中的数据
验证令牌.png
令牌的续期
对于平台本地用户,用户每次使用令牌访问接口时,通过重重验证后,重置用户令牌的有效期,例如而默认令牌有效期是20分钟,用户9点登录成功,在9点10分做了一次操作访问了一次接口,原本用户的令牌再有15分钟就会自动失效,由于用户做了一次合法的接口调用,此时令牌重置回20分钟。
刷新令牌.png
对于第三方合作平台,为了保证安全性,令牌是不会自动续期的,需要第三方自行注意过期时间并在适当时间刷新令牌,刷新令牌时每次都会生成一个新令牌替换掉旧令牌。
对于平台本地用户,令牌有效期比较短,一般设为20分钟即可(1200秒);对于第三方合作平台,令牌有效期稍长一些,一般设为2个小时(7200秒)。
通信安全性
对所有接口施加CA证书,开启https通信协议,在协议层面对数据加密防止信息泄露