Vapor UserAuthenticator从未使用,req.auth.require(User.self)总是失败.



我已经创建了一个login端点:

try LoginUserDTO.validate(content: request)
let loginUserDTO = try request.content.decode(LoginUserDTO.self)
let userService = UserService(database: request.db)
let user = try await userService.get(by: loginUserDTO.email)
if (try user.verify(password: loginUserDTO.password)) == false {
throw Abort(.unauthorized)
}
let userToken = UserToken(accessToken: generateToken(),
refreshToken: generateToken(),
accessTokenExpirationDate: generateAccessTokenExpirationDate(),
refreshTokenExpirationDate: generateRefreshTokenExpirationDate(),
user: user)
try await userToken.create(on: request.db)
request.auth.login(user)
return ClientTokenReponse(accessToken: userToken.accessToken,
refreshToken: userToken.refreshToken,
accessTokenExpirationDate: userToken.accessTokenExpirationDate,
refreshTokenExpirationDate: userToken.refreshTokenExpirationDate)

检查用户凭据,创建并返回令牌。现在我想测试我的UserAuthenticator是否工作:

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)
}
// TODO: Add additional check if accessToken is not expired yet!
if bearer.token == userToken.accessToken {
request.auth.login(loginUser.toUser())
}
}
}

所以我加了:

let protected = app.grouped([User.authenticator()])
protected.post("me") { request async throws -> String in
let user = try? request.auth.require(User.self)
if user != nil {
return "yes"
} else {
return "no"
}
}

User显然总是nil。似乎我的UserAuthenticator中的代码甚至从未执行过。我做错了什么?

好了,做了一些改变,突然它工作了:

改变了我的authenticate()方法,因为它期望在请求中传递电子邮件和密码(这是无稽之谈,因为承载在标头中发送:))。

func authenticate(bearer: BearerAuthorization, for request: Request) async throws {
guard let userToken = try await UserToken.query(on: request.db)
.join(User.self, on: UserToken.$user.$id == User.$id)
.filter(.$accessToken == bearer.token)
.first()
else {
throw Abort(.unauthorized)
}
let user = try userToken.joined(User.self)
// TODO: Add check if accessToken is not expired yet!
if bearer.token == userToken.accessToken {
request.auth.login(User(email: user.email, passwordHash: user.passwordHash))
}
}

另一个是我如何在routes文件中使用UserAuthenticator:

使用:

let protected = app.grouped(UserAuthenticator())

代替:

let protected = app.grouped([User.authenticator()])

工作!

最新更新