Basic 认证 封面
Vapor 大型教程

Basic 认证

本文给创建缩略语的接口加上 HTTP Basic 认证,只有带上正确“用户名 + 密码”的请求才能通过。

什么是 Basic 认证

HTTP Basic 认证把认证信息放在请求的 Authorization 头里。生成规则是:把“用户名:密码”拼起来后做 base64 编码,得到 token。例如用户名为 user、密码为 password 时:

base64(user:password) = dXNlcjpwYXNzd29yZAo=

那么认证头就是:

Authorization: Basic dXNlcjpwYXNzd29yZAo=

Vapor 提供了专门的 Authentication 包来处理包括 Basic 在内的各种认证,先把它加为依赖。

添加 Authentication 依赖

Package.swift 中加入 vapor/auth 包,并让 App 目标依赖 Authentication

.package(url: "https://github.com/vapor/auth.git", from: "2.0.1"),
...
.target(name: "App", dependencies: ["FluentPostgreSQL", "Authentication", "Vapor", "Leaf"]),

改完依赖后重新生成 Xcode 工程:

vapor xcode -y

让 User 支持 Basic 认证

User 遵循 BasicAuthenticatable,告诉框架用户名和密码分别对应模型里的哪个属性:

import Authentication
...

extension User: BasicAuthenticatable {
    static var usernameKey: WritableKeyPath<User, String> = \.username
    static var passwordKey: WritableKeyPath<User, String> = \.password
}

用中间件保护路由

中间件(Middleware)可以拦截请求和返回。这里的基本认证中间件会拦截请求,用 Basic 方式校验发起请求的用户是否合法;guard 中间件则保证只有通过认证的用户请求才能继续往下走。在 AcronymsController 里把创建缩略语的路由用这两个中间件包起来:

import Authentication
...
struct AcronymsController: RouteCollection {
    func boot(router: Router) throws {
        let routeGroup = router.grouped("api", "acronyms")

        let basicAuthenticationMiddleware = User.basicAuthMiddleware(using: BCryptDigest())
        let guardAuthMiddleware = User.guardAuthMiddleware()
        let protectd = routeGroup.grouped(basicAuthenticationMiddleware, guardAuthMiddleware)
        protectd.post(Acronym.self, use: createHandler)
        // routeGroup.post(Acronym.self, use: createHandler)
        ...
    }
    ...
}
注意把受保护的路由挂到 protectd 上,而不是原来的 routeGroup。注释掉的那行是改造前的写法,留着方便对比。

注册 AuthenticationProvider

上面的中间件要真正生效,还得在应用配置里注册认证服务提供者:

import Authentication
...
public func configure(_ config: inout Config, _ env: inout Environment, _ services: inout Services) throws {
    /// Register providers first
    try services.register(FluentPostgreSQLProvider())
    try services.register(AuthenticationProvider())
    ...
}

运行工程并用 Rested 工具测试:如果不带认证头,认证失败、无法创建缩略语;带上正确的用户名密码后,认证通过、创建成功。


本系列其他文章