使用 vertx 处理会话并记住登录用户

Handling sessions and remembering logged in user with vertx

当前,当用户使用网络 POST 表单、自定义身份验证器和自定义用户登录到我的网络服务器时。我将 CustomUser 放入 RoutingContext 提供的 Session 中,因为在使用 RoutingContext#setUser 时,它只会更改该请求的用户,并且一旦用户被重定向到目的地 CustomUser 的登录处理页面已丢失。

但是,新页面的 RoutingContext 中的 Session 似乎也没有任何用户存储在 auth 放置 CustomUser 的条目中,可能这是发送一个完全不同的 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 出于测试目的每次都正确。

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

我不完全确定这里出了什么问题。 Vertx 为像我这样的菜鸟提供了次优的文档,并且在没有开箱即用的情况下处理事情。任何有关如何让某人登录并像普通网站一样维护他们的会话的帮助将不胜感激。

遇到相同问题但通常跳过评论的人:

Vert.xSessionHandler依赖于CookieHandler,这里的顺序很重要

来自Vert.x examples

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