Vapor - 使用 Basic Auth 的路由总是返回 401
Vapor - Route with Basic Auth always returning 401
我是 Vapor 的新手,我已经实现了注册和登录路由。注册工作正常。每次我调用登录路由时,它似乎都有问题。每次,我都尝试使用 Basic Auth 登录注册用户,它只是 returns 401。在下面附上我的代码。
应用用户模型:
extension AppUser: ModelAuthenticatable {
static let usernameKey = \AppUser.$email
static let passwordHashKey = \AppUser.$passwordHash
func verify(password: String) throws -> Bool {
try Bcrypt.verify(password, created: self.passwordHash)
}
}
extension AppUser: JWTPayload {
func verify(using signer: JWTSigner) throws {
}
}
路由配置:
//MARK: Unprotected API
let unprotectedApi = app.routes
try unprotectedApi.register(collection: AppUserController.Unprotected())
//MARK: Password Protected API
let passwordProtectedApi = unprotectedApi.grouped(AppUser.authenticator())
try passwordProtectedApi.register(collection: AppUserController.PasswordProtected())
登录逻辑:
extension AppUserController.PasswordProtected: RouteCollection {
func login(req: Request) throws -> EventLoopFuture<Response> {
let user = try req.auth.require(AppUser.self)
let token = try req.jwt.sign(user)
let loginResponse = AppUserLoginResponse(user: user.response, accessToken: token)
return DataWrapper.encodeResponse(data: loginResponse, for: req)
}
func boot(routes: RoutesBuilder) throws {
routes.post(Endpoint.API.Users.login, use: login)
}
}
您的 login
路由目前正在返回 401,因为您已将其包含在受保护的组中,这要求用户已经登录。它通常是不受保护的。您需要一些代码来进行登录。此函数假定用户由电子邮件地址标识并以某种方式提供了密码:
private func loginExample( email: String, password: String, on: req Request) -> EventLoopFuture<Bool> {
return AppUser.query(on: req).filter(\.$email == email).first().flatMap { user in
// user will be nil if not found, following line test for this
if let user = user {
// user was identified by email
if try! user.verify(password: password) {
// password matches what is stored
request.auth.login(user)
// login has succeeded
return true
}
}
// login has failed - because either email did not match a user or the password was incorrect
return false
}
}
我通过强制调用中的 try
来保持简单以进行验证(避免 do-catch 等)。您需要在您的登录路径中使用类似此代码的内容,或许可以从 HTML 表单中解码电子邮件和密码。
我是 Vapor 的新手,我已经实现了注册和登录路由。注册工作正常。每次我调用登录路由时,它似乎都有问题。每次,我都尝试使用 Basic Auth 登录注册用户,它只是 returns 401。在下面附上我的代码。
应用用户模型:
extension AppUser: ModelAuthenticatable {
static let usernameKey = \AppUser.$email
static let passwordHashKey = \AppUser.$passwordHash
func verify(password: String) throws -> Bool {
try Bcrypt.verify(password, created: self.passwordHash)
}
}
extension AppUser: JWTPayload {
func verify(using signer: JWTSigner) throws {
}
}
路由配置:
//MARK: Unprotected API
let unprotectedApi = app.routes
try unprotectedApi.register(collection: AppUserController.Unprotected())
//MARK: Password Protected API
let passwordProtectedApi = unprotectedApi.grouped(AppUser.authenticator())
try passwordProtectedApi.register(collection: AppUserController.PasswordProtected())
登录逻辑:
extension AppUserController.PasswordProtected: RouteCollection {
func login(req: Request) throws -> EventLoopFuture<Response> {
let user = try req.auth.require(AppUser.self)
let token = try req.jwt.sign(user)
let loginResponse = AppUserLoginResponse(user: user.response, accessToken: token)
return DataWrapper.encodeResponse(data: loginResponse, for: req)
}
func boot(routes: RoutesBuilder) throws {
routes.post(Endpoint.API.Users.login, use: login)
}
}
您的 login
路由目前正在返回 401,因为您已将其包含在受保护的组中,这要求用户已经登录。它通常是不受保护的。您需要一些代码来进行登录。此函数假定用户由电子邮件地址标识并以某种方式提供了密码:
private func loginExample( email: String, password: String, on: req Request) -> EventLoopFuture<Bool> {
return AppUser.query(on: req).filter(\.$email == email).first().flatMap { user in
// user will be nil if not found, following line test for this
if let user = user {
// user was identified by email
if try! user.verify(password: password) {
// password matches what is stored
request.auth.login(user)
// login has succeeded
return true
}
}
// login has failed - because either email did not match a user or the password was incorrect
return false
}
}
我通过强制调用中的 try
来保持简单以进行验证(避免 do-catch 等)。您需要在您的登录路径中使用类似此代码的内容,或许可以从 HTML 表单中解码电子邮件和密码。