本文只是一个Demo设计,仅供学习思路,并不能用于真实的线上业务,因为有很多漏洞。
一般线上应用都需要对用户身份进行鉴权,通过身份校验的用户,都会得到一个access_token,这个凭证是全局唯一接口调用凭据,调用应用的各接口时都需使用access_token,如果token校验失败,则表明无权限访问相关接口。
注:下文access_token 和 token 是一个东西。
注:用户需要进行妥善保存access_token。线上应用的客户端一般会将token存放在前端的存储空间———Cookie中。
access_token的一些安全要求:
- access_token的存储至少要保留512个字符空间。
- access_token的有效期一般为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
那么问题来了,线上应用是怎么做身份鉴权的呢?
鉴权方式
常见的鉴权方式由如下三种:
- 账号+密码
- 账号+短信验证码
- 第三方渠道——微信
账号+密码
这个很简单,就是对比数据库中的账号密码,一致就发放token。
账号+短信验证码
这个流程相对多一些,需要先给用户手机发送一条短信,短信里包含了一个六位的数字(称作:短信验证码),用户将验证码发送到服务器,服务器判断验证码一致就发放token。
第三方渠道鉴权——微信
本文主要讲解这个,结合着加密方式做身份鉴权。
一般来说,每个微信用户都会由一个微信ID——appid,
正常的流程,会把用户的appid作为一个唯一标识进行存储,做鉴权....
正常的流程是这样,但是从安全角度来说,它不安全,并不能阻挡黑客的伪造,
比如说黑客伪造了很多appid,发送到服务器,服务器并没有能力鉴别谁是伪造的appid,那么就会造成鉴权上的绕过。
当然,微信推出了一个服务,每次获取 openid 参数时,调用微信公众平台的“获取用户基本信息”的接口去鉴别这个openid是不是伪造的。不过这个方式,只能证明这个opendid是不是微信,并不能证明这个opendid是不是自己系统的,可以结合着另一种方式,用加密做鉴权。
调用流程:
-
加密做鉴权:前端(用户)获得了微信授权openid后,将openid传输给后端,
后端先调用 微信公众平台的“获取用户基本信息”的接口去鉴别这个openid是不是伪造的,才能入库。 -
后端把回调给前端的 openid 进行加密,返回给前端。
-
前端调用 api 的时候,前端需要把授权得到的加密后的 openid 传给后端,后端先做解密校验操作,,如果解密操作失败,则认定openid非法,拒绝此次请求,成功才继续执行进行剩下的业务逻辑。
-
因为服务器同时负责加密和解密,需要采用对称加密算法,密钥安全的存储在服务器里。
-
后期只要openid能解密成功,就意味着是自己系统加密的,只要密钥不泄露,别人无法伪造。
调用流程图演示:
如果你有耐心看到这里,恭喜你能看到更远的风景,
这个方案并没有考虑完善,
比如,如果2个小时候后token失效,或者用户本地的cookie丢失,那么用户怎么才能再次才能获取token呢?
答案是:这个方案获取不了了,所有这个只是一个一次性系统。美丽的废物。
但是本文是想讨论一下,通过加密做鉴权的一些可能性。
当然,这个方案做不了,可以转换一下思路,通过其它方式做,
比如,在前端里面集成JS代码做签名,然后后台通过校验签名来确保请求是从自己的渠道发过来的。