Kitura

APIDoc Build Status - Master macOS Linux Apache 2 Slack Status

Kitura-Credentials

一个可插拔的框架,用于在使用 Kitura 的 Swift 服务器中验证用户凭据。

概要

Kitura-Credentials 是 Kitura 的身份验证中间件。 Kitura-Credentials 意识到每个应用程序都有独特的身份验证要求。 它允许将各个身份验证机制打包为插件,供其使用。

插件的范围可以从简单的基于密码的身份验证或使用 OAuth 的委托身份验证(通过 Facebook OAuth 提供程序等),到使用 OpenID 的联合身份验证。

Kitura-Credentials 支持两种主要的身份验证方案:重定向和非重定向。 重定向方案用于 OAuth2 授权码流身份验证等场景,在这种场景中,未登录的用户将被重定向到登录页面。 所有其他类型的身份验证都是非重定向的,即未经授权的请求将被拒绝(通常带有 401 Unauthorized HTTP 状态码)。 非重定向身份验证的一个示例是使用独立获取的 OAuth 访问令牌(也称为持有者令牌)进行的委托身份验证(例如,由移动应用程序或基于 Kitura 的后端的其他客户端)。

Kitura-Credentials 中间件检查请求是否属于会话。 如果是,并且用户已登录,它会更新请求的用户个人资料并传播该请求。 否则,它会按照注册顺序循环遍历非重定向插件,直到找到匹配的插件。 该插件要么成功验证请求(在这种情况下,返回用户个人资料信息),要么失败。 如果找到匹配的插件但它无法验证请求,则路由器响应中的 HTTP 状态码设置为 Unauthorized (401),或者设置为从插件返回的代码,以及 HTTP 标头,并且请求不会传播。 如果未找到匹配的插件,并且请求属于会话且存在重定向插件,则请求将被重定向。 否则,路由器响应中的 HTTP 状态码设置为 Unauthorized (401),或者设置为从插件返回的第一个代码以及 HTTP 标头,并且请求不会传播。 如果身份验证成功,则请求的用户个人资料将被设置为从身份验证插件收到的用户个人资料信息。

在 OAuth2 授权码流的范围内,身份验证由特定插件执行。 Kitura-Credentials 尝试通过调用插件来登录和验证第一个请求,如果成功,则将相关数据存储在会话中,以便验证该会话中的任何后续请求。 该插件不会被调用来处理会话范围内的其他请求。

目录

Swift 版本

最新版本的 Kitura-Credentials 需要 Swift 4.0 或更高版本。 您可以通过此 链接 下载此版本的 Swift 二进制文件。 不保证与其他 Swift 版本的兼容性。

用法

添加依赖项

Kitura-Credentials 包添加到应用程序的 Package.swift 文件中的依赖项中。 将 "x.x.x" 替换为最新的 Kitura-Credentials release

.package(url: "https://github.com/Kitura/Kitura-Credentials.git", from: "x.x.x")

Credentials 添加到目标的依赖项中

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

导入包

import Credentials

示例

Codable 路由

在 Codable 路由中,您通过定义符合插件 TypeSafeCredentials 实现的 Swift 类型来实现单个凭据插件。 然后可以通过在路由签名中定义它来将其应用于 codable 路由

router.get("/authenticated") { (userProfile: BasicAuthedUser, respondWith: (BasicAuthedUser?, RequestError?) -> Void) in
    print("authenticated \(userProfile.id) using \(userProfile.provider)")
    respondWith(userProfile, nil)
}

要将多个身份验证方法应用于路由,您定义一个符合 TypeSafeMultiCredentials 的类型,并将其添加到您的 codable 路由签名中。 该类型必须定义一个 TypeSafeCredentials 类型数组,这些类型将按顺序查询,以尝试验证用户。 它还必须定义一个初始化器,该初始化器从 TypeSafeCredentials 类型的实例创建自身的一个实例。

如果用户可以使用 HTTP basic 或令牌进行身份验证,并且定义了类型 BasicAuthedUserTokenAuthedUser,则可以如下实现

public struct MultiAuthedUser : TypeSafeMultiCredentials {

    public let id: String
    public let provider: String

    public static var authenticationMethods: [TypeSafeCredentials.Type] = [BasicAuthedUser.self, TokenAuthedUser.self]

    public init(successfulAuth: TypeSafeCredentials) {
        self.id = successfulAuth.id
        self.provider = successfulAuth.provider
    }
}

router.get("/multiauth") { (userProfile: MultiAuthedUser, respondWith: (MultiAuthedUser?, RequestError?) -> Void) in
    print("authenticated \(userProfile.id) using \(userProfile.provider)")
    respondWith(userProfile, nil)
}

原始路由

有关 OAuth2 授权码流身份验证示例,请参见 Kitura-Sample

以下是使用 Facebook OAuth2 访问令牌的基于令牌的身份验证示例。此示例使用 CredentialsFacebookToken 插件验证 post 请求。

首先创建 Credentials 的一个实例和凭据插件的一个实例

import Credentials
import CredentialsFacebook

let credentials = Credentials()
let fbCredentialsPlugin = CredentialsFacebookToken()

您还可以使用指定的初始化器或直接设置来设置 options(传递给插件的选项字典)。

现在注册插件

credentials.register(fbCredentialsPlugin)

Kitura-Credentials 框架是 RouterMiddleware。 要将其连接到所需的路径,请使用 Router 方法之一。 成功进行身份验证后,request.userProfile 将包含 UserProfile 的一个实例,其中包含使用插件从 OAuth 服务器收到的用户个人资料信息。

router.post("/collection/:new", middleware: credentials)
router.post("/collection/:new") {request, response, next in
   ...
   let profile = request.userProfile
   let userId = profile.id
   let userName = profile.displayName
   ...
   next()
}

注意:凭据中间件必须在任何路由处理程序之前注册,如上例所示。 在其他路由处理程序之前未能注册凭据中间件可能会导致在受保护的路由上暴露未经授权的数据。

插件列表

API 文档

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

社区

我们喜欢讨论服务器端 Swift 和 Kitura。 加入我们的 Slack 与团队会面!

许可证

该库已获得 Apache 2.0 许可。 完整的许可证文本可在 LICENSE 中找到。