系统安全可能往往是被大家所忽略的,我们的很多系统说是在互联网上”裸奔”一点都不夸张,很容易受到攻击,系统安全其实是一个复杂且庞大的话题,若要详细讲来估计用几本书的篇幅都讲不完,基于此本篇及下一篇会着重讲解在我们开发系统过程中遇到的一些安全校验机制,希望能起到抛砖引玉的作用,望各位在开发过程中多多思考不要只局限于功能实现上,共勉~
在系统安全、身份验证以及权限授权方面通常来说有各种各样的处理方式,但大多都比较复杂。在很多框架和系统里,涉及安全和身份验证的工作往往都比较繁琐,并且代码量也巨大,基于此也出现了一些相关的协议和相关库 我们今天就一起来了解一下相关的内容
    
    
    1.常见认证规范/协议
   
    
    
    1.1OAuth2
   
OAuth2 是一种协议规范,定义了几种用来身份验证和权限授权的处理方式。它是一种可扩展的协议规范,涵盖了几种复杂的使用场景。并且包含了基于第三方身份验证的处理方法。我们常见的”使用微信登陆”、”使用 QQ 登陆”等第三方登陆方式的底层技术就是基于 OAuth2 实现的。
    
    
    1.2OpenID Connect
   
OpenIDConnect 是另一种基于 OAuth2 的协议规范。它扩展了 OAuth2 的部分功能,让以前相对模糊的功能变得可操作性更强。常见的 Google 登陆就是基于 OpenID Connect 实现的。
    
    
    1.3OpenAPI
   
OpenAPI 是一套构建 API 的开放标准。FastAPI 是基于 OpenAPI 构建而成。
OpenAPI 支持以下几种安全机制:
    
     1.apiKey:应用指定的 key 来自于
    
   
    (1) 查询参数
    
    (2) header 信息
    
    (3) cookie 信息
   
    
     2.http:支持标准的 http 身份验证系统,包括:
    
   
    bearer:头信息 Authorization 的内容中带有 Bearer 和 token 信息,继承自 OAuth2
    
    HTTP 基本认证
    
    HTTP 摘要认证
   
    
     3.oauth2
    
   
    
     4.openIdConnect
    
   
FastAPI 通过引入 fastapi.security 模块,可以支持以上所有安全机制,并且简化了使用方法。
    
    
    2.JWT
   
    
    
    2.1JWT 的概念
   
JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息。
    
    
    2.2JWT 的组成
   
一个 JWT 实际上就是一个字符串,它由三部分组成:头部、载荷与签名。将这三段信息文本用.链接一起就构成了 Jwt 字符串。就像这样:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
    
    
    头部(Header)
   
    JWT 的头部承载两部分信息:
    
    1、声明类型,这里是 jwt
    
    2、声明加密的算法,通常直接使用 HMAC SHA256
    
    我们使用 base64 解析一下 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 这个子串 可以得到:
   
{
   
  "typ": "JWT",
  "alg": "HS256"
}
可以看出: 在头部指明了签名算法是 HS256 算法。
    
    
    2.3载荷(Payload)
   
    载荷就是存放有效信息的地方。这些有效信息包含三个部分
    
    1、标准中注册的声明
    
    2、公共的声明
    
    3、私有的声明
   
    标准中注册的声明 (建议但不强制使用) :
    
    1、iss(Issuer): 签发人
    
    2、sub(Subject): 主题
    
    3、aud(Audience): 受众
    
    4、exp(Expiration Time): 过期时间,这个过期时间必须要大于签发时间
    
    5、nbf(Not Before): 生效时间
    
    6、iat(Issued At): 签发时间
    
    7、jti(JWT ID) : JWT 的唯一身份标识,主要用来作为一次性 token,从而回避重放攻击。
   
    公共的声明:
    
    公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息。但不建议添加敏感信息,因为该部分在客户端可解密。
   
    私有的声明:
    
    私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为 base64 是对称解密的,意味着该部分信息可以归类为明文信息。
   
我们使用 base64 解析一下 eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9 就可以得到 之前定义的一个 payload:
{
   
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
    
    
    2.4签名(Signature)
   
    JWT 的第三部分是一个签证信息,这个签证信息由三部分组成:
    
    1、header (base64 后的)
    
    2、payload (base64 后的)
    
    3、secret
   
这个部分需要 base64 加密后的 header 和 base64 加密后的 payload 使用.连接组成的字符串,然后通过 header 中声明的加密方式进行加盐 secret 组合加密,然后就构成了 JWT 的第三部分。
 
