@warplydesigned thanks a lot for flagging this. There was an API change in the final release of Vapor from the time the article was written, and we fixed it in the sample projects, but missed in the article.
I’m confused by the logic on “Adding the Login Endpoint”.
Typically a fresh login will require a username (email) password. The server side will find a user object for that username or email address, validate the passwords and return a token + user of some kind.
In case I’m missing something big, I fail to see how the current implementation would work.
Hi @kdeda, and I’m sorry for the delay here, I missed your comment.
You’re correct. But in this case, instead of sending the login and password in the HTTP Body, Vapor’s User.authenticator() middleware decodes them from the Authentication header, and provide the user object in case they are valid.
You can use this website to understand how this header is generated based on the username and password:
Hi @natanrolnik , I have followed the tutorial carefully but I have problem I can’t login the by runing unit test it’s throw always failure unauthorised.
this the scenario i followed in my unit test I create user, logout, login.
this the router.
let passwordProtector = userRoutes.grouped(User.authenticator())
passwordProtector.post("login", use: loginUser)
this the login handler
fileprivate func loginUser(_ req: Request) throws → EventLoopFuture {
let user = try req.auth.require(User.self)
let token = try user.createToken(source: .login)
return token.create(on: req.db).flatMapThrowing{
NewSession(token: token.value, user: try user.asPublic())
}
}
this my unit test call.
let login = userURI + “login”
try app.test(.POST, login, beforeRequest: { (req) in
let loginuser = [“username”: userName,
“password”: password
]
try req.content.encode(loginuser)
}, afterResponse: { (response) in
let recivedSession = try response.content.decode(NewSession.self)
XCTAssertNotNil(recivedSession.token)
})
Hi there, if I want to make sure both the email and username is unique, what’s the best way to chain the futures together? I have this, which works, but I find it kind of ugly! Also I wonder if it’s more efficient to just do one query rather than two? But then I need the future to respond with an error code instead of a Bool?