VaporAuth 是一个用于权限断言的库。
dependencies: [
.package(url: "https://github.com/Myoland/VaporAuth.git", from: "1.0.0"),
]
import VaporAuth
public struct User: AuthCarrier {
enum CodingKeys: String, CodingKey {...}
public var subject: SubjectClaim
public var scopes: ScopeClaim
public func verify(using signer: JWTSigner) throws {...}
public init(...) {...}
}
let app = try Application(.detect())
app.routes
.grouped(User.authenticator())
.grouped(\User.scope, "a_scope b_scope")
.on(.GET, "a", use: handler)
app.routes
.grouped(User.authenticator())
.grouped(\User.subject, "sub")
.grouped(\User.scope, ["a_scope", "b_scope"])
.on(.GET, "a", use: handler)
public struct ScopeClaim: JWTClaim, Equatable {
public var value: [String]
public init(value: [String]) {
self.value = value
}
public static func == (lhs: ScopeClaim, rhs: ScopeClaim) -> Bool {
return Set(rhs.value) == Set(lhs.value)
}
}
extension ScopeClaim: Comparable {
public static func < (lhs: ScopeClaim, rhs: ScopeClaim) -> Bool {...}
}
extension ScopeClaim: Guardable {
public func hasAuth(required: ScopeClaim) -> Bool {
required == self || required < self
}
}
app.routes
.grouped(User.authenticator())
.grouped(\User.scope, ["a_scope", "b_scope"])
.on(.GET, "a", use: handler)
let scope = ScopeClaim(value: ["a", "b"])
let encoded = try JSONEncoder().encode(scope)
let decoded = try JSONDecoder().decode(ScopeClaim.self, from: encoded)
为了比较所需权限和携带权限之间的值,我们使用了谓词的理念。
谓词是对获取或内存中过滤的搜索进行约束的逻辑条件的定义。
通常,要确定用户是否有权访问处理程序,我们只需要一个布尔值,一个结果。因此,我们不关心所需的权限或任何其他事情,我们只关心给定的权限和结果。这就是谓词的作用。
请注意,谓词支持基本的逻辑运算,例如 &&
, ||
, !
。
在 VaporAuth 中,我们提供 AuthPredicate
来帮助我们确定用户是否具有权限。
AuthPredicate
有两种实现: AuthBasePredicate
和 AuthFieldPredicate
。
let a = AuthBasePredicate<Carrier> { user in
user.sub == "some"
}
let b = AuthFieldPredicate(\Carrier.iss, "any")
let c = a && b
let _ = a.hasAuth(carrier: user)
let _ = b.hasAuth(carrier: user)
let _ = c.hasAuth(carrier: user)
在检查权限之前,我们需要对用户进行身份验证。
当你的信息遵循 JWTPayload
协议时,很容易进行身份验证。
app.routes
.grouped(User.authenticator())
.on(.GET, "a", use: handler)