0Pricing
Swift Academy · 课时

中间件与身份验证

添加横切逻辑并保护路由。

中间件与身份验证 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

什么是中间件

中间件位于传入请求与路由处理程序之间,可以检查或修改请求和响应。它非常适合用于日志记录、CORS、错误处理和身份验证。

import Vapor

中间件协议

自定义中间件需要遵循 AsyncMiddleware 并实现 respond(to:chainingTo:)。完成所需工作后,调用 next.respond(to:) 继续处理链。

struct LogMiddleware: AsyncMiddleware {
    func respond(to req: Request, chainingTo next: AsyncResponder) async throws -> Response {
        req.logger.info("Incoming: " + req.url.path)
        return try await next.respond(to: req)
    }
}

全局注册中间件

将中间件添加到 app.middleware,即可让它处理每个请求。顺序很重要:中间件会按照添加顺序运行。

app.middleware.use(LogMiddleware())

内置中间件

Vapor 提供了实用的中间件:ErrorMiddleware 将抛出的错误转换为响应,FileMiddleware 提供静态文件服务,CORSMiddleware 处理跨域请求。

let cors = CORSMiddleware(configuration: .default())
app.middleware.use(cors)

特定路由的中间件

将路由与中间件分组,即可只对部分路由应用中间件。组内的路由会受到保护,其他路由则不会。

let protected = app.grouped(LogMiddleware())
protected.get("dashboard") { req in "Secret dashboard" }

身份验证概念

Vapor 的身份验证系统包含两部分:Authenticatable 模型(您的用户)和 Authenticator 中间件,后者负责验证凭据并将用户存储在请求中。

final class AppUser: Model, Content, Authenticatable {
    static let schema = "users"
    @ID(key: .id) var id: UUID?
    @Field(key: "username") var username: String
    @Field(key: "password_hash") var passwordHash: String
    init() {}
}

编写基本身份验证器

AsyncBasicAuthenticator 处理 HTTP 基本身份验证。实现 authenticate(basic:for:):查找用户、验证密码,并在成功后调用 req.auth.login(user)。

struct UserAuthenticator: AsyncBasicAuthenticator {
    func authenticate(basic: BasicAuthorization, for req: Request) async throws {
        guard let user = try await AppUser.query(on: req.db)
            .filter(\.$username == basic.username).first() else { return }
        if try Bcrypt.verify(basic.password, created: user.passwordHash) {
            req.auth.login(user)
        }
    }
}

使用 Bcrypt 哈希密码

绝不要存储明文密码。Vapor 内置 Bcrypt,可在注册时进行哈希处理,并在登录时验证密码。哈希是单向的;验证时会将候选密码与存储的哈希值进行比较。

let hash = try Bcrypt.hash("s3cret")
let ok = try Bcrypt.verify("s3cret", created: hash) // true

使用守卫保护路由

将身份验证器与 AppUser.guardMiddleware() 结合使用,该方法会以 401 拒绝未经身份验证的请求。将受保护的路由置于两者之后的分组中。

let protected = app.grouped(
    UserAuthenticator(),
    AppUser.guardMiddleware()
)
protected.get("me") { req -> String in
    let user = try req.auth.require(AppUser.self)
    return user.username
}

读取已认证用户

在受保护的处理程序中,使用 req.auth.require(_:)(用户不存在时抛出错误)或 req.auth.get(_:)(返回可选值)获取已登录用户。这是将数据限定为当前用户数据的方式。

app.get("profile") { req -> String in
    let user = try req.auth.require(AppUser.self)
    return "Hello, " + user.username
}

令牌认证

对于接口,持有者令牌很常见。令牌模型遵循 ModelTokenAuthenticatable,从而让 Vapor 验证 Authorization: Bearer ... 标头,并自动加载关联用户。

let tokenProtected = app.grouped(
    UserToken.authenticator(),
    AppUser.guardMiddleware()
)

快速检查:中间件与身份验证

请确认您是否理解。

回顾:中间件与身份验证

您已经学会了拦截请求并保护请求:

  • 中间件(AsyncMiddleware)包装请求;您可以全局注册,也可以按路由组注册。
  • 使用 ErrorMiddleware 和 CORSMiddleware 等内置组件。
  • 让用户遵循 Authenticatable,编写一个 Authenticator,然后调用 req.auth.login。
  • 使用 Bcrypt 进行哈希处理,使用 guardMiddleware() 保护路由,并通过 req.auth.require 读取用户。

常见问题解答

「中间件与身份验证」课时是免费的吗?

是的 — 「中间件与身份验证」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「中间件与身份验证」这节课中我会学到什么?

添加横切逻辑并保护路由。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「中间件与身份验证」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 路由与请求处理
  2. 内容与 JSON 编码
  3. Fluent ORM 与模型
  4. 中间件与身份验证
← 返回 Swift Academy