您的位置: 首页 > 新闻中心

    从token的使用到API安全

    作者:威海网络公司 日期:2018-03-21 点击:1651

    目录

    1. 为什么要使用Token

    2. Token的安全性

    3. JWT(Json Web Token)

    4. JWT能力有限

    1. 为什么要使用Token

    java web使用基于服务器的认证(传统方式Session)

    由于HTTP协议是无状态的, 就是说如果我们使用用户名和密码来认证一个用户, 在下一次请求的时候, 我们的应用程序不会知道我们是谁, 我们不得不重新认证。为了解决这个问题,就有了session,利用请求cookie实现。(Session有状态)

    由于原来的API认证用户名和密码是存储在服务器端的,由应用完成每次请求的合法性验证。

    这种认证存在问题:

    1. 很容易收到CSRF攻击,由于该攻击利用cookie获得session,如果是金融类网站且有跳转的,就很危险。

    2. 会话多了,服务器session就多,内存占用多,同时限制了伸缩性。(与负载均衡服务器也会有耦合)

    Token的使用不存在上述问题

    1. 基于token的认证是无状态的,不会将用户信息记录到服务器或者会话中。

    2. 可以实现完全的动静分离,实现单页面APP。

    3. 更符合RESTful的规范。

    每一个请求都需要token, 在HTTP header中发送, 以便我们保持无状态HTTP请求。

    我们也需要将服务器设置为能使用Access-Control-Allow-Origin: * 接受来自所有域的请求

    OAuth进行授权一般使用在开放平台中,对于API的保护来说,使用OAuth过于复杂,主要还是使用JWT。

    2.Token的安全性

    token会过期,用户需要再次登录或者使用refreshToken重新获取一个token。

    例如:token可以在30分钟过期,refreshToken可以久一点,一旦refreshToken过期了,就需要用户重新登录了。

    从token的使用到API安全

    token时序举例

    在使用无状态的Token的时候,需要注意:

    1. Refresh Token有效期较长,所以它应该在服务器端有状态,以增强安全性,确保注销销毁。

    2. 应该考虑使用二次认证来增强敏感操作的安全性。

    Token不能防重放、不能防篡改

    • 疑问1:如何防止重放(Replay Attacks),HTTPS数据加密是否可以防止重放攻击?

      解答:HTTPS不能防止重放,但加密可以有效防止明文数据被监听。

      可以利用Nonce(这个是请求的唯一标识,一般使用UUID来标识),或者timeStamp(误差不超过15分钟)做防重放。

    • 疑问2:如何防止篡改?

      解答:添加签名。

      请求所有的内容都被加入签名计算,所以请求的任何修改,都会造成签名失败。

    3.JWT(Json Web Token)

    既然token比较好用,有没有规范呢,JWT。

    首先看下JWT生成的token样子:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICAgIm5hbWUiOiJUb3B2aWV3ZXJzIi wKICAgICJhZ2UiOiIzMCIsCiAgICAib3JnIjoiQklUQ09NIgp9.55TF72vSkj-a64aHHiYN5eoZ9Nb4w5vb45PsER7x_AB

    3.1 JWT的构成

    header、payload、signature三部分

    第一部分:header

    jwt的头部承载两部分信息,完整的头部例如:

    {

    `typ`:'JWT',//声明类型,这里是jwt

    `alg`:'HS256'//声明加密的算法 通常直接使用 HMAC SHA256

    }

    然后将头部进行base64编码,构成了第一部分:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

    第二部分:payload

    {

    "name":"Topviewers",

    "age":"30",

    "org":"BITCOM"

    }

    • 标准中注册的声明

    • iss: jwt签发者

    • sub: jwt所面向的用户

    • aud: 接收jwt的一方

    • exp: jwt的过期时间,这个过期时间必须要大于签发时间

    • nbf: 定义在什么时间之前,该jwt都是不可用的.

    • iat: jwt的签发时间

    • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

    • 公共的声明

      公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

    • 私有的声明

      私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

    然后将其进行base64加密,得到Jwt的第二部分:

    ewogICAgIm5hbWUiOiJUb3B2aWV3ZXJzIiwKICAgICJhZ2UiOiIzMCIsCiAgICAib3JnIjoiQklUQ09NIgp9

    第三部分:signature

    jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

    • header (base64后的)

    • payload (base64后的)

    • secret

    这个部分需要base64编码后的header和base64编码后的payload使用‘.’(点)连接组成的字符串,然后通过header中

    声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分:

    55TF72vSkj-a64aHHiYN5eoZ9Nb4w5vb45PsER7x_AB

    这部分无法在客户端解密,密钥secret是保存在服务端的,服务端会根据这个密钥进行生成token和验证,所以需要保护好。

    3.2 JWT 实现

    JWT实现代码,引入即可,代码实现了token签发与验签

    <dependency>

    <groupId>com.auth0</groupId>

    <artifactId>java-jwt</artifactId>

    <version>3.1.0</version>

    </dependency>

    4. JWT能力有限

    JWT能力有限,主要实现针对不同组织和用户实现API权限控制、访问控制,开放平台API访问几乎都是这种方式。

    JWT不能防止客户端数据被拦截篡改,同样也无法阻止重放。

    以上只是理论,在应用场景上还需要仔细设计。

    1. 微信公众号对接上,使用了很多token,例如access_token、fresh_token。

    2. token背后的权限、访问控制才是设计的要点,例如结合shiro或者spring Security。


    本文由威海网络公司半岛科技整理发布!2018.03.21

    分享到:

    上一条:App 里的权限秘密:大数据下,个人隐私荡然无存?

    下一条:电商后台:实例解读促销系统