知识清单 - 安全性
安全性
- OAuth: 用于身份验证的开放标准。
- JWT(JSON Web Token): 用于安全传输信息的开放标准。
一、OAuth
OAuth(Open Authorization)是一个用于身份验证和授权的开放标准,用于在客户端和服务提供者之间进行安全的资源共享。OAuth 的目标是允许第三方应用程序(客户端)在用户授权的情况下,访问在其他服务上托管的用户资源,而不需要将用户的凭证直接提供给第三方。
OAuth(Open Authorization)是一个用于身份验证和授权的开放标准,用于在客户端和服务提供者之间进行安全的资源共享。OAuth 的目标是允许第三方应用程序(客户端)在用户授权的情况下,访问在其他服务上托管的用户资源,而不需要将用户的凭证直接提供给第三方。
OAuth 的核心角色有三个:
资源所有者(Resource Owner): 拥有受保护资源的用户。资源所有者是授权的主体。
客户端(Client): 通过请求访问受保护资源的第三方应用程序。客户端是资源的使用者。
授权服务器(Authorization Server): 负责验证资源所有者并颁发访问令牌(Access Token)给客户端。授权服务器和资源服务器可以是同一个实体,也可以是不同的实体。
资源服务器(Resource Server): 存储和提供受保护资源的服务器。资源服务器根据客户端的访问令牌决定是否允许客户端访问资源。
OAuth 的工作流程通常分为以下步骤:
客户端注册: 客户端在授权服务器上注册,并获得客户端标识和密钥。
授权请求: 客户端引导用户到授权服务器,请求授权。这通常包括重定向用户到授权服务器的认证页面。
用户授权: 用户登录并在授权服务器上授权客户端访问其资源。用户授权的方式包括授权码授权、密码授权、客户端凭证授权等。
授权颁发: 授权服务器验证用户身份,并颁发访问令牌给客户端。
资源访问: 客户端使用访问令牌请求资源服务器,以获取受保护资源。
资源响应: 资源服务器验证访问令牌,并向客户端提供受保护资源。
OAuth 2.0 和 OAuth 1.0a:
OAuth 1.0a: 使用签名机制,要求客户端提供签名,以确保请求的完整性。虽然安全,但相对繁琐。
OAuth 2.0: 简化了 OAuth 1.0a 的流程,通过使用访问令牌(Access Token)来提供对资源的访问。虽然不如 1.0a 安全,但更简便且广泛使用。
OAuth 2.0 主要包括授权码授权、密码授权、客户端凭证授权、隐式授权等多种授权方式。
OAuth 在许多 Web 应用程序和服务中广泛应用,为用户提供了安全且方便的第三方应用访问权限的机制。
二、JWT
JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在网络上安全地传输信息。JWT 是一种紧凑的、自包含的方式,用于在各方之间作为 JSON 对象传递信息。主要用于身份验证和在不同系统之间安全地传递声明。
JWT 的结构:
JWT 由三部分组成,这三部分由点(.
)分隔开:
Header(头部): 包含了令牌的类型(JWT)和所使用的签名算法,通常以 Base64 编码的 JSON 字符串表示。
json{ "alg": "HS256", "typ": "JWT" }
Payload(负载): 包含了声明(claims),声明是关于实体(通常是用户)和其他数据的声明。有三种类型的声明:注册声明、公共声明、私有声明。
json{ "sub": "1234567890", "name": "John Doe", "admin": true }
Signature(签名): 使用编码的头部、编码的负载和一个密钥(secret)来创建。签名的目的是验证消息的发送方以及消息在传递过程中没有被篡改。
plaintextHMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
工作流程:
认证: 用户提供用户名和密码进行认证,服务端验证用户身份。
颁发 JWT: 服务端使用私钥签发 JWT,并将其返回给客户端。
存储 JWT: 客户端通常将 JWT 存储在本地,例如在浏览器的 localStorage 中。
携带 JWT: 客户端在后续请求中通过将 JWT 放入请求头或其他适当位置,将其携带到服务端。
验证和解析 JWT: 服务端收到请求后,验证 JWT 的签名,然后解析其中的信息。
授权: 根据 JWT 中的信息,服务端对客户端进行授权。
优势:
轻量且紧凑: JWT 的结构简单,因此相较于传统的身份验证机制,它更轻量且在网络传输中更紧凑。
可扩展性: 可以通过添加自定义声明来扩展 JWT 的功能,适应不同的应用场景。
无状态性: 由于 JWT 包含了所有必要的信息,服务器不需要在本地存储用户的会话信息,因此可以实现无状态的认证。
跨域支持: JWT 可以在不同域之间传输,并且可以通过配置 CORS(跨域资源共享)来支持跨域通信。
自包含性: JWT 包含了所有必要的信息,因此客户端可以解析 JWT 来获取用户的信息,而不必在每个请求中都去查询服务器。
安全注意事项:
使用 HTTPS: 所有的 JWT 通信都应该在安全的通道上进行,即使用 HTTPS。
令牌有效期: JWT 可以设置有效期,确保在一段时间后令牌失效。
避免敏感信息: 不要在 JWT 中存储敏感信息,因为 JWT 的内容可以被解码。
避免过长有效期: 不要设置过长的 JWT 有效期,以减少窃取风险。
JWT 是一种通用且强大的身份验证和授权机制,适用于多种应用场景,包括单点登录、API 认证等。
示例(使用 Node.js 和 jsonwebtoken 库):
const jwt = require('jsonwebtoken')
// 选择加密算法和设置密钥
const algorithm = 'HS256'
const secretKey = 'your_secret_key'
// 构建头部
const header = {
alg: algorithm,
typ: 'JWT'
}
// 构建负载
const payload = {
sub: '1234567890',
name: 'John Doe',
admin: true,
exp: Math.floor(Date.now() / 1000) + 3600 // 设置过期时间为1小时后
}
// 生成JWT
const token = jwt.sign(payload, secretKey, { algorithm })
console.log(token)
验证和解析 JWT 步骤:
获取 JWT: 从客户端收到 JWT。
拆分 JWT: 使用点号(.)拆分 JWT,分为头部、负载和签名三部分。
验证签名: 使用与生成 JWT 时相同的加密算法和密钥,对头部和负载进行签名验证。
解析负载: 将 Base64 解码后的负载部分转换为 JSON 对象,获取其中的声明信息。
验证和解析 JWT 示例(使用 Node.js 和 jsonwebtoken 库):
const jwt = require('jsonwebtoken')
// 从客户端收到的JWT
const receivedToken = 'your_received_jwt'
// 选择加密算法和设置密钥
const algorithm = 'HS256'
const secretKey = 'your_secret_key'
try {
// 拆分JWT
const [encodedHeader, encodedPayload, signature] = receivedToken.split('.')
// 验证签名
const isSignatureValid = jwt.verify(receivedToken, secretKey, {
algorithms: [algorithm]
})
if (isSignatureValid) {
// 解码负载
const decodedPayload = jwt.decode(receivedToken)
console.log('Signature is valid')
console.log('Decoded Payload:', decodedPayload)
} else {
console.log('Signature is invalid')
}
} catch (error) {
console.error('Error:', error.message)
}
上述示例中,我们使用 Node.js 中 jsonwebtoken 库来验证和解析 JWT。jwt.verify
函数用于验证 JWT 的签名,如果签名有效,就可以使用jwt.decode
函数将负载解码为 JSON 对象。请注意,实际中需要适应应用场景选择合适的算法、密钥管理和声明内容,并且要处理异常情况,如签名无效或解码错误。
优势:
轻量和紧凑: JWT 是一种轻量级、紧凑的标准,适合在网络上快速传输信息。
自包含性: JWT 包含了所有必要的信息,客户端可以解码 JWT 以获取用户信息,减少了对服务器的查询次数。
无状态性: 由于 JWT 包含所有必要的信息,服务器不需要在本地存储用户的会话信息,实现了无状态的认证。
可扩展性: 可以通过添加自定义声明来扩展 JWT 的功能,适应不同的应用场景。
跨域支持: JWT 可以在不同域之间传输,并且可以通过配置 CORS(跨域资源共享)来支持跨域通信。
安全性: 当使用合适的加密算法和密钥管理时,JWT 可以提供较高的安全性。
广泛应用: JWT 广泛应用于身份验证、单点登录、API 认证等场景。
不足:
无法撤销: 一旦 JWT 生成并在客户端存储,服务器无法撤销或立即使其失效。过期时间是唯一可控制的机制。
不适用于保密信息: JWT 的内容可以通过 Base64 解码,因此不适合存储敏感信息,尽管可以使用加密算法提高安全性。
过期时间问题: 如果过期时间设置过短,可能导致用户频繁重新登录;如果设置过长,可能增加被滥用的风险。
无法处理状态变更: JWT 无法处理用户在会话期间的状态变更,例如用户被禁用或角色变更。
不适用于大量数据: JWT 适用于小型信息传输,但对于大量数据可能效率较低。
对称加密问题: 使用对称加密算法时,密钥的分发和管理可能成为挑战。
总体而言,JWT 是一种非常有用的工具,特别是在分布式系统和前后端分离的应用中。在使用时,需要权衡其优势和不足,根据具体的应用场景和安全需求来选择合适的配置和实践。