客户端常常涉及用户操做,用户登陆须要使用用户名和密码,为了安全起见,暴露密码的过程越少越好。解决方案以下:redis
- 使用Https协议
1)客户端使用帐户密码登陆,服务器返回token。
服务器收到客户端帐户和密码登陆,生成<token, id>键值对,例如<123, 1>,并将信息存在redis或者memcache中。
2)客户端每次操做都携带token做为身份验证 。
客户端使用代token的API访问服务器,服务器将数据返回给客户端。
例如:
客户端访问 https://api.server.com/user/info?token=123,服务器根据token对应的id返回数据。
3)客户端退出登陆,token失效。
客户端退出登陆,服务器从缓存中删除键值对。
使用Https协议解决了通讯的明文问题,可是使用携带token的方式,身份验证依赖token,若是Url被黑客截取,黑客就能够利用token进行任何操做。
- URL签名
API中携带token,有可能会致使token泄露,URL签名方式就是用于解决携带token的问题。
1)客户端使用帐户密码登陆,服务器返回token。
服务器收到客户端帐户和密码登陆,生成<id, token>键值对,例如<1, 123>,并将信息存在redis或者memcache中。
2)客户端每次操做都对URL签名 。
客户端使用代签名的API访问服务器,服务器将数据返回给客户端。
例如:
sign = md5(https://api.server.com/user/info?token=123)
客户端访问 https://api.server.com/user/info?userId=1&sign=xxxx,服务器根据userId读取缓存的token,并按照规则进行md5散列生成签名,将生成的签名和URL中携带签名对比,若是相同则操做合法,并返回数据。可是这个方案存在缺陷,若是url被截取,任何人均可以经过url获取用户信息。
改进:
sign = md5(https://api.server.com/user/info?timestamp=1425860700&token=123)
客户端访问 https://api.server.com/user/info?userId=1×tamp=1425860700&sign=xxxx,服务器根据先拿URL上的timestamp与当前时间对比,若是时间差超过必定时间(好比30s),则认为非法操做;若是时间差合法,则继续后面操做。
3)客户端退出登陆,token失效。
客户端退出登陆,服务器从缓存中删除键值对。
URL签名的方式只能保护token不被泄露,可是没法保证敏感数据不被截取。
- AES对称加密
URL签名保证了token不被泄露,可是并不能保证敏感数据泄露。
1)客户端使用帐户密码登陆,服务器返回token。
服务器收到客户端帐户和密码登陆,生成<id, token>键值对,例如<1, 123>,并将信息存在redis或者memcache中。
2)客户端每次操做都对URL签名 。
客户端使用代签名的API访问服务器,服务器将数据返回给客户端。
例如:
sign = md5(https://api.server.com/user/info/name?timestamp=1425860700&token=123)
客户端POST访问https://api.server.com/user/info/name?userId=1×tamp=1425860700&sign=xxx修更名字,这时候就会暴露本身的名字。
改进:
secret_name = AES(name, token)
sign = md5(https://api.server.com/user/info/secret_name?timestamp=1425860700&token=123)
客户端POST访问https://api.server.com/user/info/secret_name?userId=1×tamp=1425860700&sign=xxx修更名字,服务器使用AES解密secret_name,再进行修改操做。
3)客户端退出登陆,token失效。
客户端退出登陆,服务器从缓存中删除键值对。
- 更进一步安全 使用DES加密操做,Https原理就是先使用RSA加密获取key,再使用AES加密通信; 涉及敏感信息都须要输入密码确认,密码用不存在客户端。