zoukankan      html  css  js  c++  java
  • Web API与JWT认证

    ​JWT(Json Web Token)定义了一种使用Json形式在网络间安全地传递信息的简洁开放的标准(RFC 7519)。JWT使用数字签名确保信息是可信的。

    一、Session认证和Token认证
    Http协议本身是无状态的,如果用户向服务器传递了用户名和密码进行了用户认证,那么下一次请求时用户还是需要进行同样的认证,因为根据Http协议,我们无法知道请求是由哪个用户发出的。所以,为了能识别哪个用户,免去每次都进行验证的麻烦,就有了传统的Session认证和token认证方案。

    a) Session认证
    Session认证的方案为:第一次用户认证请求通过时,服务器端存储用户的登录信息,然后在响应时传递给浏览器,浏览器保存为cookie,下次请求时把cookie发送给服务器,服务器根据cookie信息来识别是哪个用户。
    Session认证适用于单个服务器的场合,如果用户增多,需要部署多个服务器时,Session认证就会暴露问题。因为每个用户在认证后,服务器都会记录Session,一般保存在内存中,随着认证用户增多,服务器开销也会增大;而且认证用户的后续请求都需要到这台保存了自己Session的服务器上验证Cookie。在多集群分布式的场合,这就造成了性能瓶颈,对负载均衡、应用的扩展都会造成影响。
    进程外Session通过将Session保存在数据库或硬盘中可以解决服务器内存开销的问题,但仍然不便于扩展。

    b) Token认证
    Token认证也是无状态的,不需要在服务端保存认证用户的信息,它的认证流程为:用户使用用户名密码请求服务器;服务器验证用户,如果验证通过就发给用户一个token;客户端保存token,并在之后的每次请求都附上token;服务端验证token、返回数据。
    Token认证机制不需要保存认证用户的信息、也不需要考录用户在那台服务器登录,可以很好地适应应用的扩展。
    token的体积很小,请求服务端时,可以被附在URL、Header或是Post参数中。而且token中包含了用户相关的必要、非私密的相信,免去了服务端再次查询数据库的开销。

    c) JWT的使用场景

    最常用于对已经登录用户的认证,比如单点登录,只需在每次请求中都附上JWT,JWT体积小巧且支持跨域、多语言。
    JWT也可以用于信息传输,因为有根据payload和header计算出的签名的保护,可以确保传递的信息不被篡改。

    三、JWT的构成
    JWT由Header、Payload、Signature三部分构成,之间用点号风格,构成xx.yy.zz的形式。
    a) Header声明了token类型、算法类型(HMAC SHA256或RSA),比如
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    然后对header做Base64URL编码。
    b) Payload中保存了声明信息,声明信息有标准声明、公开声明、自定义声明三种类型,前两种声明在相关的标准中已经规定https://www.iana.org/assignments/jwt/jwt.xhtml,推荐但不强制使用,标准声明举例有:

    iss: jwt签发者
    sub: jwt所面向的用户
    aud: 接收jwt的一方
    exp: jwt的过期时间,这个过期时间必须要大于签发时间
    nbf: 定义在什么时间之前,该jwt都是不可用的.
    iat: jwt的签发时间
    jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
    发送方和接收方也可以自定声明。
    {
      "sub": "1234567890",
      "name": "John Doe",
      "admin": true
    }
    载荷信息也使用Base64URL编码。


    c) Signature,签证信息是根据Header、Payload的Base64URL编码以及密钥(Secret)加密生成的,加密算法使用header中定义的类型。

    d) Secret信息只保存在服务端,服务端为客户端签发jwt token要使用Secret,后续对客户端递交的jwt的验证也要使用Secret,所以一定要防止Secret的泄露。

    四、JWT的使用

    var secret = "h3h5k9kll789";
    //JWT签发
    var payload = new Dictionary<string, object>
    {
      { "UserID",123},
      {"UserName","admin" }
    };
    //指定HMAC加密算法
    IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
    IJsonSerializer serializer = new JsonNetSerializer();
    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
    IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
    var token = encoder.Encode(payload, secret);

    //JWT验证及解析
    IJsonSerializer serializer1 = new JsonNetSerializer();
    IDateTimeProvider provider1 = new UtcDateTimeProvider();
    IJwtValidator validator1 = new JwtValidator(serializer1, provider1);
    IBase64UrlEncoder urlEncoder1 = new JwtBase64UrlEncoder();
    IJwtDecoder decoder = new JwtDecoder(serializer1, validator1, urlEncoder1);
    //解析出PayLoad
    var json = decoder.Decode(token, secret, verify: true);



    学习资料:如鹏网.net提高班http://www.rupeng.com/News/10/4603.shtml
    http://www.jianshu.com/p/576dbf44b2ae
    https://jwt.io/

  • 相关阅读:
    vue 组件通信(全)
    clickoutside 代码实现
    reset css 样式重置
    vue computed 无法deep的问题
    sessionStorage的总结
    Windows系统maven安装配置
    Windows系统JDK安装配置
    开篇
    JIT即时编译器
    CLR基础
  • 原文地址:https://www.cnblogs.com/zhixin9001/p/7768652.html
Copyright © 2011-2022 走看看