SwiftJWT 3.6.200

SwiftJWT 3.6.200

由以下人员维护:Matt KilnerDavid JonesMathieu BarnachonDanny SungAndrew LeesSwift-at-IBM



 
依赖
BlueRSA~> 1.0
BlueECC~> 1.1
LoggerAPI~> 1.7
KituraContracts~> 1.2
BlueCryptor~> 1.0
 

SwiftJWT 3.6.200

  • IBM 和 Kitura 项目的作者

Kitura

APIDoc Build Status - Master macOS Linux Apache 2 Slack Status

SwiftJWT

Swift 的大头实现 JSON Web Token (JWT)。JWT 提供了轻便和紧凑的信息传输格式,可以在各方之间传输信息,并且由于 JWT 是数字签名的,因此信息可以被验证和信任。

有关 JSON Web Token 的更多信息,包括其用例和如何工作,我们建议您访问 jwt.io

注意:作为 JWS 发送的 JWT 对数据进行加密,因此绝不要发送任何敏感或机密信息在 JWT 中。此库目前不支持 JWE。

Swift 版本

Swift-JWT 最新版本需要 Swift 4.0 或更高版本。您可以点击这个 链接 下载 Swift 二进制文件。与其他 Swift 版本的兼容性无法保证。

用法

Swift 包管理器

添加依赖项

Swift-JWT 包添加到你的应用程序 Package.swift 文件中的依赖项中。将 "x.x.x" 替换为最新的 Swift-JWT 版本

.package(url: "https://github.com/IBM-Swift/Swift-JWT.git", from: "x.x.x")

SwiftJWT 添加到你的目标的依赖项

.target(name: "example", dependencies: ["SwiftJWT"]),

导入包

import SwiftJWT

CocoaPods

要在使用 CocoaPods 的项目中包含 Swift-JWT,请将 SwiftJWT 添加到你的 Podfile 中

pod 'SwiftJWT'

开始使用

JWT 模型

在其压缩形式中,JSON Web Tokens 由三个用点(.)分隔的 Base64Url 编码 JSON 部分组成。
这些部分是:头部(Headers)、声明(Claims)和签名(Signature)。因此,JWT 通常如下所示:xxxxx.yyyyy.zzzzz

头部

Header 结构体包含由 RFC7515 定义的自定义 JSON Web Token 的头部字段。
"typ" 头部默认为 "JWT"。当您对 JWT 进行签名时,“alg” 头部将设置为算法名称。
其他头部字段可以在初始化 Header 结构体时设置,也可以通过直接修改头部对象来更改。

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)
ClaimsExamples

本库包括一些按其在线规范定义的 Claims 结构体示例。

  • ClaimsStandardJWT,如 RFC7519 中定义。
  • ClaimsMicroProfile,如 此处 定义。
  • ClaimsOpenID.swift,如 此处 定义。

JWT

JWT 结构体代表一个 JSON Web Token 的 HeaderClaims
您可以通过解码 JWT 字符串或提供 JWT 头部和声明来初始化 JWT。

let myJWT = JWT(header: myHeader, claims: myClaims)

签名和验证 JSON Web token

创建公钥和私钥

要使用 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

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>

注意:签名函数设置了头部的 alg (算法) 字段。

使用 JWTVerifier 验证 JWT

JWTVerifier 结构体包含了可以用来验证 JWT 的算法。

使用与所需 RSA 算法对应的静态函数初始化 JWTVerifier。

let jwtVerifier = JWTVerifier.rs256(publicKey: publicKey)

要验证已签名的 JWT 字符串,请调用静态 verify 函数,传入 JWT 字符串和 JWTVerifier。

let verified = JWT<MyClaims>.verify(signedJWT, using: jwtVerifier)

如果签名验证成功,verified 字段将是 bool 类型的值为真。

受支持算法

用于签名和验证 JWT 的受支持算法如下:

  • RS256 - 使用 SHA-256 的 RSASSA-PKCS1-v1_5
  • RS384 - 使用 SHA-384 的 RSASSA-PKCS1-v1_5
  • RS512 - 使用 SHA-512 的 RSASSA-PKCS1-v1_5
  • HS256 - 使用 SHA-256 的 HMAC
  • HS384 - 使用 SHA-384 的 HMAC
  • HS512 - 使用SHA-512进行HMAC
  • ES256 - 使用SHA-256和P-256曲线进行ECDSA
  • ES384 - 使用SHA-384和P-384曲线进行ECDSA
  • ES512 - 使用SHA-512和P-521曲线进行ECDSA
  • PS256 - 使用SHA-256进行RSA-PSS
  • PS384 - 使用SHA-384进行RSA-PSS
  • PS512 - 使用SHA-512进行RSA-PSS
  • none - 不对JWT进行签名或验证

注意:ECDSA和RSA-PSS算法需要Swift 4.1及更高版本。

验证声明

validateClaims函数验证JWT实例的标准Date声明。如果Claims对象中存在以下声明,则会验证

  • exp(过期日期)
  • nbf(开始日期)
  • iat(发行日期)

此方法返回ValidateClaimsResult - 一个结构体,列出了各种验证失败的 reasons。如果验证成功,则返回ValidateClaimsResult.successleeway参数是秒数,表示标准Date声明超出指定时间外的有效时间。这可以用来弥补发行者和验证者之间的时钟偏差。

let validationResult = verified.validateClaims(leeway: 10)
if validationResult != .success {
    print("Claims validation failed: ", validationResult)
}

从JWT字符串解码JWT

可以从JWT字符串初始化JWT结构体。如果提供了JWTVerifier,它将在初始化之前验证签名

let newJWT = try JWT<MyClaims>(jwtString: signedJWT, verifier: jwtVerifier)

JWTEncoder和JWTDecoder

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的 BodyEncoder和BodyDecoder协议,所以它们可以用作自定义编解码器,用于在可编码路由中发送和接收JWT

 router.encoders[MediaType(type: .application, subType: "jwt")] = { return jwtEncoder }
 router.decoders[MediaType(type: .application, subType: "jwt")] = { return jwtDecoder }

这允许使用JWT进行信息交换。通过发送和接收JWT,您可以确保发送者是其所称的人,并验证内容没有被篡改。

API 文档

更多信息请访问我们的 API 参考

社区

我们热衷于讨论服务器端 Swift 和 Kitura。加入我们的 Slack,与团队见面!

许可证

本库采用 Apache 2.0 许可。完整许可证文本可在 LICENSE 中找到。