Java >> Java tutorial >  >> Tag >> HTTP

Vert.x omdirigerer http til https

De endelige løsninger, jeg kom med, er vist nedenfor, og de er ækvivalente. Ideen i begge tilfælde er at have en http-server (som selvfølgelig lytter på port 80), der omdirigerer hvert opkald til en https-server.

Så i mit tilfælde kan jeg gøre præcis, hvad jeg vil, fordi http://mydomain.it er omdirigeret til https://mydomain.it som forventet. For eksempel når jeg ringer til

http://mydomain.it/api/polynomial/laguerre

Der er en http-server i live, der modtager anmodningen, men derefter kaster den bolden med det samme til

https://mydomain.it/api/polynomial/laguerre

Selvfølgelig, hvis du direkte kalder https-versionen, sker dette "mellemliggende" trin ikke.

Brug af Vert.x

Svaret fra Hugo i ovenstående indlæg giver en valid løsning ved hjælp af Vertx. Jeg har et hovedpunkt, der ser sådan ud:

public class MainVerticle extends AbstractVerticle {

  @Override
  public void start() throws Exception {

    //Deploy the HTTPS server
    vertx.deployVerticle(
      "com.albertomiola.equations.http.HttpsServerVerticle",
      new DeploymentOptions().setInstances(n)
    );

    //Deploy the HTTP server
    vertx.deployVerticle(
      "com.albertomiola.equations.http.HttpServerVerticle",
      new DeploymentOptions().setInstances(1)
    );
  }

}

Det første hjørne er det "rigtige" websted, fordi det indeholder al den logik, jeg har brug for i min webservice (routere, handlere, modeller...), og det ser sådan ud:

public class HttpsServerVerticle extends AbstractVerticle {

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    // Setup the HTTPS
    var httpOptions = new HttpServerOptions()
      .setCompressionSupported(true)
      .setPort(443)
      .setSsl(true)
      .setPemTrustOptions(...)
      .setPemKeyCertOptions(...);

    // Start the server and the routes
    var server = vertx.createHttpServer(httpOptions);
    var router = Router.router(vertx);

    //Start
    server
      .requestHandler(router)
      .listen(ar -> {
        if (ar.succeeded()) {
          startPromise.complete();
        } else {
          startPromise.fail(ar.cause());
        }
      });
  }

}

Det andet loddepunkt er i stedet bare en http-server, der permanent omdirigerer (med 301) til https-versionen af ​​webserveren. Her er koden:

public class HttpsServerVerticle extends AbstractVerticle {

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    var server = vertx.createHttpServer(httpOptions);
    var router = Router.router(vertx);

    //Start
    server
      .requestHandler(r -> {
          r.response()
           .setStatusCode(301)
           .putHeader("Location", r.absoluteURI().replace("http", "https"))
           .end();
      });
  }

}

På denne måde er der 2 servere aktive, men faktisk er det ligesom hvis der kun var 1, fordi http-serveren (port 80) omdirigerer hvert opkald til https-serveren (port 443).

Brug af Nginx

Den anden tilgang, som jeg har testet, kræver nginx, men den gør de samme ting, som jeg har gjort i ovenstående eksempel. Den lytter til http-anmodninger på port 80 og omdirigerer dem derefter til https-versionen.

  1. Installer Nginx på min Ubuntu-server (eller hvad du nu har)
  2. Gå ind i konfigurationsfilen, som er i /etc/nginx/nginx.conf i mit tilfælde
  3. Tilføj nedenstående kode

    http {
        server {
                listen         80;
                server_name    mydomain.it;
                return         301 https://$server_name$request_uri;
        }
    
        //other code...
    }
    
    1. Genstart med systemctl restart nginx

Nu omdirigeres hvert opkald til http-versionen til https-versionen. Tak til brugerinjektøren, som har foreslået mig på denne måde.

Jeg bruger denne tilgang, fordi jeg foretrækker ikke at have en enkelt vertikel kun for http-versionen. Også denne artikel fra Vertx-webstedet siger, at denne tilgang er gyldig:

Det er almindeligt at eksponere HTTP-servere i produktion gennem en front HTTP-server / proxy som Nginx, og lade den bruge HTTPS til indgående forbindelser. Vert.x kan også afsløre HTTPS af sig selv for at give ende-til-ende-kryptering.

Så ja, opsæt https med Vertx (jeg vil anbefale letsencrypt-certificeringer), men omdiriger også opkald til https med nginx.

Jeg troede fejlagtigt, at jeg kunne gøre noget bestemt med Vertx for at håndtere denne omdirigering, men det er ikke muligt. Efter forslagene fra personerne i dette svar OG nogle gode google rundt, har jeg lært, at denne tilgang er almindelig, og det er det, jeg bør gøre!


Java tag