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了。