使用 Swift 实现的 JSON Web Token。JWT 提供了一种轻量且紧凑的格式,用于在各方之间传输信息。由于 JWT 经过数字签名,因此可以验证和信任该信息。
有关 JSON Web Token 的更多信息、其用例以及工作原理,我们建议访问 jwt.io。
提醒: 作为 JWS 发送的 JWT 不加密数据,因此切勿在 JWT 中发送任何敏感或机密信息。此库目前不支持 JWE。
最新版本的 Swift-JWT 需要 Swift 5.2 或更高版本。您可以通过此链接下载此版本的 Swift 二进制文件。不保证与其他 Swift 版本的兼容性。
将 Swift-JWT
包添加到应用程序的 Package.swift
文件中的依赖项中。将 "x.x.x"
替换为最新的 Swift-JWT
release。
.package(url: "https://github.com/Kitura/Swift-JWT.git", from: "x.x.x")
将 SwiftJWT
添加到目标的依赖项中
.target(name: "example", dependencies: ["SwiftJWT"]),
import SwiftJWT
要在使用 CocoaPods 的项目中包含 Swift-JWT
,请将 SwiftJWT
添加到您的 Podfile
pod 'SwiftJWT'
以其紧凑形式,JSON Web Token 由三个部分组成,这些部分是 Base64Url 编码的 JSON,以点 (.) 分隔。
这些部分是:标头、声明和签名。因此,JWT 通常如下所示:xxxxx.yyyyy.zzzzz
Header 结构包含 RFC7515 定义的 JSON Web Token 标头的字段。
"typ" 标头将默认为 "JWT"。当您签署 JWT 时,"alg" 标头将设置为算法名称。
其他标头字段可以在初始化标头时设置,也可以直接在标头对象上更改它们。
let myHeader = Header(kid: "KeyID1")
声明是关于实体(通常是用户)和其他数据的陈述。声明是通过创建符合 Claims
协议的 Swift 类型来定义的。此类型的字段表示将使用 JWT 共享的信息。
RFC7519 中定义了推荐声明的列表。
struct MyClaims: Claims {
let iss: String
let sub: String
let exp: Date
let admin: Bool
}
let myClaims = MyClaims(iss: "Kitura", sub: "John", exp: Date(timeIntervalSinceNow: 3600), admin: true)
此库包含一些示例 Claims
结构,这些结构根据其在线规范定义。
JWT 结构表示 JSON Web Token 的 Header
和 Claims
。
您可以通过解码 JWT 字符串或提供 JWT 标头和声明来初始化 JWT。
let myJWT = JWT(header: myHeader, claims: myClaims)
要使用 RSA 算法签名和验证 JWT,您必须提供公钥和私钥。这可以是使用以下终端命令生成的 .key 文件的内容
$ ssh-keygen -t rsa -b 4096 -m PEM -f privateKey.key
# Don't add a passphrase
$ openssl rsa -in privateKey.key -pubout -outform PEM -out privateKey.key.pub
这将在您的系统上创建一个公钥和私钥对,私钥的内容可以使用以下代码传递到 Swift 变量中
let privateKeyPath = URL(fileURLWithPath: getAbsolutePath(relativePath: "/path/to/privateKey.key"))
let privateKey: Data = try Data(contentsOf: privateKeyPath, options: .alwaysMapped)
let publicKeyPath = URL(fileURLWithPath: getAbsolutePath(relativePath: "/path/to/publicKey.key"))
let publicKey: Data = try Data(contentsOf: publicKeyPath, options: .alwaysMapped)
有关创建椭圆曲线公钥和私钥的详细信息,请查看 BlueECC README.txt。
结构体 JWTSigner 包含可用于签署 JWT 的算法。
使用与所需的 RSA 算法对应的静态函数初始化 JWTSigner
let jwtSigner = JWTSigner.rs256(privateKey: privateKey)
要生成签名的 JWT 字符串,请在 JWT 实例上调用 sign
函数,并传入 JWTSigner
let signedJWT = try myJWT.sign(using: jwtSigner)
生成的 signedJWT
将是以下形式的 String
<encoded header>.<encoded claims>.<signature>
注意: sign 函数设置标头的 alg(算法)字段。
结构体 JWTVerifier 包含可用于验证 JWT 的算法。
使用与所需的 RSA 算法对应的静态函数初始化 JWTVerifier
let jwtVerifier = JWTVerifier.rs256(publicKey: publicKey)
要验证已签名的 JWT 字符串,请调用静态 verify
函数,并传入您的 JWT 字符串和 JWTVerifier
let verified = JWT<MyClaims>.verify(signedJWT, using: jwtVerifier)
如果签名已验证,则 verified
字段将是一个 bool
,值为 true。
支持的用于签名和验证 JWT 的算法有
注意:ECDSA 和 RSA-PSS 算法需要最低 Swift 版本 4.1。
validateClaims
函数验证 JWT 实例的标准 Date
声明。如果以下声明存在于 Claims
对象中,则将对其进行验证
该方法返回 ValidateClaimsResult
- 一个结构体,列出了验证失败的各种原因。如果验证成功,则返回 ValidateClaimsResult.success
。 leeway
参数是以秒为单位的 TimeInterval
,标准 Date
声明在该指定时间之外有效。这可用于解释颁发者和验证者之间的时钟偏差。
let validationResult = verified.validateClaims(leeway: 10)
if validationResult != .success {
print("Claims validation failed: ", validationResult)
}
可以从 JWT 字符串初始化 JWT 结构体。如果提供了 JWTVerifier,则它将在初始化之前用于验证签名
let newJWT = try JWT<MyClaims>(jwtString: signedJWT, verifier: jwtVerifier)
JWTEncoder 和 JWTDecoder 类使用与 JSONEncoder 和 JSONDecoder 相同的 API 编码和解码 JWT 字符串
let jwtEncoder = JWTEncoder(jwtSigner: jwtSigner)
let jwtString = try jwtEncoder.encodeToString(myJWT)
let jwtDecoder = JWTDecoder(jwtVerifier: jwtVerifier)
let jwt = try jwtDecoder.decode(JWT<MyClaims>.self, fromString: jwtString)
由于 JWTEncoder 和 JWTDecoder 符合 KituraContract's BodyEncoder 和 BodyDecoder 协议,因此它们可以用作 自定义编码器,在 Codable 路由中发送和接收 JWT
router.encoders[MediaType(type: .application, subType: "jwt")] = { return jwtEncoder }
router.decoders[MediaType(type: .application, subType: "jwt")] = { return jwtDecoder }
这允许在信息交换中使用 JWT。通过发送和接收 JWT,您可以确保发送者就是他们所说的身份,并验证内容是否未被篡改。
有关更多信息,请访问我们的 API 参考。
我们喜欢讨论服务器端 Swift 和 Kitura。加入我们的 Slack 认识团队!
此库在 Apache 2.0 许可下获得许可。完整的许可文本可在 LICENSE 中获得。