Request
中的auth
属性可以让你进行用上验证,并且提供了一些获取常见的授权头信息的方法。
Authorization
authorization header
是从客户端发送凭证的好地方:
Authorization: xxxxxxxxxx
你可以通过req.auth.header
获取authorization header
basic
和bearer
是两种常见的模式。
Basic
基本授权模式包含了用字符串链接的用户名和密码,并采用base64
编码。
Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
上面是一个基本授权的header
。如果你想对基本授权了解更多,可以查看wikipedia。
下面是通过req.auth
获取这个header
:
guard let credentials = req.auth.header?.basic else {
throw Abort.badRequest
}
basic header
返回一个APIKey
类型的凭证。
class APIKey: Credentials {
let id: String
let secret: String
}
Bearer
承载模式包含一个API key。
Authorization: Bearer apikey123
获取头部信息时返回的是一个AccessToken
类型的凭证。
class AccessToken: Credentials {
let string: String
}
Raw
要访问原始授权头,请使用req.auth.header?.header
。
Credentials
Basic和Bearer返回的都是遵守Credentials
协议的类型。你随时可以创建自定义的遵守Credentials
协议的Credentials
对象来进行授权操作,或者手动创建APIKey, AccessToken, 或Identifier。
let key = AccessToken(string: "apikey123")
Input
你也可以从表单或者Json数据中创建凭证。
guard
let username = req.data["username"]?.string,
let password = req.data["password"]?.string
else {
throw Abort.badRequest
}
let key = APIKey(id: username, secret: password)
Login
只要你有了遵守Credentials
的内容,就可以进行用户登录了。
try req.auth.login(credentials)
调用成功后用户就会登录并开启会话。只要cookie有效,用户就一直处在登录状态。
Authenticate
登录会调用提供给AuthMiddleware
的Auto.User
模型的authenticate
方法。确保添加你所要使用的所有凭证类型。
使用Realm除外。
Identifier
另外一种重要的凭证类型就是Identifier
类型。当Vapor从vapor-auth
获取User
时时使用的这种类型。这是用户手动登录的一种便捷方法。
static func authenticate(credentials: Credentials) throws -> Auth.User {
switch credentials {
...
case let id as Identifier:
guard let user = try User.find(id.id) else {
throw Abort.custom(status: .badRequest, message: "Invalid identifier.")
}
return user
...
}
}
添加一个使用Credentials
为Identifier
类型的案例很简单,只需要使用它来查找用户:
let id = Identifier(id: 42)
try req.auth.login(id)
你现在可以使用用户的identifier
进行手动登录了。
Ephermeral(临时的)
如果只是单纯地用户登录请求,不要使用持久存储。
req.auth.login(credentials, persist: false)
Note:持久化的验证需要支持
Identifier
类型的凭证才能正常工作。
User
默认的request.auth.user()
返回的是授权的Auth.User
,它需要被转化成你内部使用的User
。
为Request
上添加一个便捷方法是简化这步的好方法。
extension Request {
func user() throws -> User {
guard let user = try auth.user() as? User else {
throw Abort.custom(status: .badRequest, message: "Invalid user type.")
}
return user
}
}
现在可以通过try req.user()
方法获取自己定义的User
了。