Rob
Rob

Reputation: 98

Handling sessions and remembering logged in user with vertx

Currently when a user logs in to my web server using a web POST form, a custom authenticator and a custom user. I have the CustomUser put into the Session provided by the RoutingContext because, when using RoutingContext#setUser it only changes the user for that request and as soon as the user is redirected from the login processing page to their destination the CustomUser has been lost.

However, it also seems as though the Session in RoutingContext for the new page doesn't have any user stored in the entry where the auth placed the CustomUser, could this be sending a completely different Session?

Routing:

    //ROUTE DEFINITIONS
    //  SESSION AND COOKIE
    router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)).setNagHttps(false)); //TODO SSL
    router.route().handler(CookieHandler.create());
    //  STATIC
    router.route("/").handler(new StaticHandler()); //BASE
    router.route("/admin").handler(new StaticHandler()); //ADMIN PAGE
    //  FORM REQUESTS
    router.route("/login").handler(new AuthAndRegHandler(new CustomAuth(), dbController)); //LOGIN REQUEST
    router.route("/logout").handler(new AuthAndRegHandler(new CustomAuth(), dbController)); //LOGOUT REQUEST
    //  AJAX
    router.route("/ajax/updateInvoice").handler(new AjaxHandler());
    //  ERRORS
    router.route().failureHandler(new ErrorHandler());
    router.route().handler(handle -> {
        handle.fail(404);
    });
    //END DEFINITIONS

AuthAndRegHandler:

public class AuthAndRegHandler extends AuthHandlerImpl {

    private DatabaseController db;
    private CustomAuth authProvider;

    public AuthAndRegHandler(CustomAuth authProvider, DatabaseController db) {
        super(authProvider);
        this.db = db;
        this.authProvider = authProvider;
    }

    @Override
    public void handle(RoutingContext event) {
        Logger log = LoggerFactory.getLogger(this.getClass());
        HttpServerResponse response = event.response();
        HttpServerRequest request = event.request();
        Session session = event.session();
        String requestedPath = request.path();

        authProvider.setJdbc(db.getJdbc()); //returns a JDBCClient

        if(requestedPath.equalsIgnoreCase("/login")) {
            if(request.method() != HttpMethod.POST)
                event.fail(500);
            else {
                request.setExpectMultipart(true);
                request.endHandler(handle -> {
                    MultiMap formAtts = request.formAttributes();
                    String email = formAtts.get("email");
                    String pw = formAtts.get("password");

                    log.info(email + ":" + pw + " login attempt");

                    authProvider.authenticate(new JsonObject()
                            .put("username", email)
                            .put("password", pw), res -> {
                                if(res.succeeded()) {
                                    CustomUser userToSet = (CustomUser) res.result();

                                    session.put("user", userToSet);
                                    log.info("Login successful for " + email);
                                    response.putHeader("Location", "/").setStatusCode(302).end();
                                } else {
                                    event.fail(500);
                                    log.error("Auth error for " + request.host());
                                }
                            });
                });
            }
        }
    }
}

CustomAuth returns true every time for testing purposes.

StaticHandler

    CustomUser user = session.get("user");
    event.setUser(user);
    response.putHeader("Content-Type", "text/html");

    if(user != null) {
        log.info(user.principal().getString("email") + " user detected");
        event.setUser(user);
    } else 
        log.info("Null user request detected"); //Constantly outputs, even after a login form has been submitted

I'm not entirely sure what's going wrong here. Vertx has sub-optimal documentation for a rookie like myself on session and handling things without their out-of-the-box implementations. Any help on how to log someone in and maintain their session like a normal website would be appreciated.

Upvotes: 2

Views: 4315

Answers (1)

Alexey Soshin
Alexey Soshin

Reputation: 17721

For those who stumble upon the same problem, but usually skip the comments:

Vert.x SessionHandler depends on CookieHandler, and the order is important here.

From the Vert.x examples:

router.route().handler(CookieHandler.create());
router.route().handler(sessionHandler);

Upvotes: 3

Related Questions