Search code examples
authenticationbackendbasic-authenticationlogoutvapor

How to Create login and logout using Vapor (Basic Authentication)


I want to create login and logout methods and routes. I've done already basic authentication but now I'm stuck how to continue. How should I do that, should I use sessions?

I'm using Vapor 3, Swift 4 and PostgreSQL and followed this tutorial https://medium.com/rocket-fuel/basic-authentication-with-vapor-3-c074376256c3. I'm total newbie so I appreciate a lot if you can help me!

my User model

struct User : Content, PostgreSQLModel, Parameters {
    var id : Int?
    private(set) var email: String
    private(set) var password: String
}

extension User: BasicAuthenticatable {
    static let usernameKey: WritableKeyPath<User, String> = \.email
    static let passwordKey: WritableKeyPath<User, String> = \.password
}

UserController.swift, registering user.

private extension UserController {

    func registerUser(_ request: Request, newUser: User) throws -> Future<HTTPResponseStatus> {

        return try User.query(on: request).filter(\.email == newUser.email).first().flatMap { existingUser in

            guard existingUser == nil else {
                throw Abort(.badRequest, reason: "a user with this email already exists" , identifier: nil)
            }

            let digest = try request.make(BCryptDigest.self)
            let hashedPassword = try digest.hash(newUser.password)
            let persistedUser = User(id: nil, email: newUser.email, password: hashedPassword)

            return persistedUser.save(on: request).transform(to: .created)
        }
    }
}

Solution

  • So in Basic authentication there is no 'logout' per se as there's no login. With HTTP Basic Auth you transmit the user's credentials with each request and validate those credentials with each request.

    You mention sessions, but first it's important to know what type of service you are providing? Are you providing an API or a website? They are different use cases and have different (usually) methods for authentication and login.

    For an API you can use Basic Authentication and generally in your login function you exchange the credentials for some sort of token. Clients then provide that token with future requests to authenticate the user. To log out you simply destroy the token in the backend so it is no longer valid.

    For a website, things are a little different since you can't manipulate the requests like you can with a normal client (such as setting the Authorization header in the request). HTTP Basic authentication is possible in a website, though rarely used these days. What traditionally happens is you submit the user's credentials through a web form, authenticate them and then save the authenticated user in a session and provide a session cookie back to the browser. This authenticates the user in future requests. To log a user out you just remove the user from the session.

    Vapor's Auth package provides everything you need to do both of these scenarios. See https://github.com/raywenderlich/vapor-til for examples of both