Request
中的auth
屬性可以讓你進(jìn)行用上驗(yàn)證榜配,并且提供了一些獲取常見的授權(quán)頭信息的方法凯旋。
Authorization
authorization header
是從客戶端發(fā)送憑證的好地方:
Authorization: xxxxxxxxxx
你可以通過req.auth.header
獲取authorization header
basic
和bearer
是兩種常見的模式。
Basic
基本授權(quán)模式包含了用字符串鏈接的用戶名和密碼墙歪,并采用base64
編碼。
Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
上面是一個(gè)基本授權(quán)的header
。如果你想對(duì)基本授權(quán)了解更多拱层,可以查看wikipedia。
下面是通過req.auth
獲取這個(gè)header
:
guard let credentials = req.auth.header?.basic else {
throw Abort.badRequest
}
basic header
返回一個(gè)APIKey
類型的憑證宴咧。
class APIKey: Credentials {
let id: String
let secret: String
}
Bearer
承載模式包含一個(gè)API key根灯。
Authorization: Bearer apikey123
獲取頭部信息時(shí)返回的是一個(gè)AccessToken
類型的憑證。
class AccessToken: Credentials {
let string: String
}
Raw
要訪問原始授權(quán)頭掺栅,請(qǐng)使用req.auth.header?.header
烙肺。
Credentials
Basic和Bearer返回的都是遵守Credentials
協(xié)議的類型。你隨時(shí)可以創(chuàng)建自定義的遵守Credentials
協(xié)議的Credentials
對(duì)象來進(jìn)行授權(quán)操作氧卧,或者手動(dòng)創(chuàng)建APIKey, AccessToken, 或Identifier桃笙。
let key = AccessToken(string: "apikey123")
Input
你也可以從表單或者Json數(shù)據(jù)中創(chuàng)建憑證。
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
的內(nèi)容沙绝,就可以進(jìn)行用戶登錄了搏明。
try req.auth.login(credentials)
調(diào)用成功后用戶就會(huì)登錄并開啟會(huì)話。只要cookie有效闪檬,用戶就一直處在登錄狀態(tài)星著。
Authenticate
登錄會(huì)調(diào)用提供給AuthMiddleware
的Auto.User
模型的authenticate
方法。確保添加你所要使用的所有憑證類型粗悯。
使用Realm除外虚循。
Identifier
另外一種重要的憑證類型就是Identifier
類型。當(dāng)Vapor從vapor-auth
獲取User
時(shí)時(shí)使用的這種類型样傍。這是用戶手動(dòng)登錄的一種便捷方法横缔。
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
...
}
}
添加一個(gè)使用Credentials
為Identifier
類型的案例很簡單,只需要使用它來查找用戶:
let id = Identifier(id: 42)
try req.auth.login(id)
你現(xiàn)在可以使用用戶的identifier
進(jìn)行手動(dòng)登錄了衫哥。
Ephermeral(臨時(shí)的)
如果只是單純地用戶登錄請(qǐng)求茎刚,不要使用持久存儲(chǔ)。
req.auth.login(credentials, persist: false)
Note:持久化的驗(yàn)證需要支持
Identifier
類型的憑證才能正常工作炕檩。
User
默認(rèn)的request.auth.user()
返回的是授權(quán)的Auth.User
斗蒋,它需要被轉(zhuǎn)化成你內(nèi)部使用的User
。
為Request
上添加一個(gè)便捷方法是簡化這步的好方法笛质。
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
}
}
現(xiàn)在可以通過try req.user()
方法獲取自己定義的User
了泉沾。