我是蒸气的新手,我正在尝试添加一个登录端点。我从https://docs.vapor.codes/security/authentication/#bearer
跟踪蒸汽文档的承载身份验证我目前的实现:
struct UserAuthenticator: AsyncBearerAuthenticator {
func authenticate(bearer: BearerAuthorization, for request: Request) async throws {
typealias User = App.User
let loginUser = try request.query.decode(LoginUserDTO.self)
guard let user = try await User.query(on: request.db)
.filter(.$email == loginUser.email)
.first(),
let userId = user.id else {
throw Abort(.notFound)
}
guard let userToken = try await UserToken.query(on: request.db)
.filter(.$user.$id == userId)
.first() else {
throw Abort(.notFound)
}
if bearer.token == userToken.value {
request.auth.login(loginUser.toUser())
}
}
}
我的用户Model
类有一个扩展名:
extension User: ModelAuthenticatable {
static var usernameKey = User.$email
static var passwordHashKey = User.$passwordHash
func verify(password: String) throws -> Bool {
self.passwordHash == password.generateHash(salt: salt)
}
}
我的路由文件有这个受保护的路由:
let protected = app.grouped(UserAuthenticator())
protected.post("login") { request async throws -> ClientTokenReponse in
let user: User = try request.auth.require(User.self)
return ClientTokenReponse(token: "token")
}
当我尝试用postman登录时,我总是得到401 Unauthorized,如果我尝试调试UserAuthenticator类,它甚至不会在断点处停止。我做错了什么?
你把两件分开的事情混在一起了,登录和路由保护。
AsyncBearerAuthenticator
不应该用于登录调用,只用于用户应该已经使用令牌登录的路由。
首先,用户应该呼叫login以获取令牌。这仍然可以通过某种方式加以保护,通常用户必须提供密码。你可以在蒸汽文档中看到这一点。
你的UserAuthenticator
应该只验证令牌是有效的,并将其匹配到一个用户。