Akka HTTP CORS headers not being set

I’m attempting to use akka-http-cors to implement CORS while connecting a React app running on localhost:3000 to an Akka HTTP REST API running on localhost:8080.

I’ve followed the documentation but it doesn’t seem that the ‘Access-Control-Allow-Origin’ header is being sent.

The response headers I’m getting when making a POST request to the Akka HTTP API are:

HTTP/1.1 400 Bad Request

    Server: akka-http/10.2.7

    Date: Sat, 12 Mar 2022 18:50:21 GMT

    Content-Type: text/plain; charset=UTF-8

    Content-Length: 124

While the request headers are:

POST /api/posts HTTP/1.1

    Host: localhost:8080

    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0

    Accept: application/json, text/plain, */*

    Accept-Language: en-US,en;q=0.5

    Accept-Encoding: gzip, deflate, br

    Content-Type: application/json

    Content-Length: 336

    Origin: http://localhost:3000

    DNT: 1

    Connection: keep-alive

    Referer: http://localhost:3000/

    Sec-Fetch-Dest: empty

    Sec-Fetch-Mode: cors

    Sec-Fetch-Site: same-site

    Sec-GPC: 1

I’m concatenating four routes together (which might be connected to the problem) but I have tried both wrapping individual routes in a cors directive

val routes = cors() {
    pathPrefix("api" / "posts") {
      get {
        path(Segment) { id =>
          val uuid = UUID.fromString(id)
          complete((postActor ? GetPostByID(uuid)).mapTo[Post])
        } ~
          pathEndOrSingleSlash {
            complete((postActor ? GetAllPosts).mapTo[List[Post]])
          }
      } ~
        post {
          entity(as[Post]) { post =>
            complete((postActor ? CreatePost(post)).map(_ => StatusCodes.Created))
          }
        } ~
        put {
          path(Segment) { id =>
            val uuid = UUID.fromString(id)
            entity(as[Post]) { post =>
              complete((postActor ? UpdatePost(uuid, post)).map(_ => StatusCodes.OK))
            }
          }
        } ~
        delete {
          path(Segment) { id =>
            val uuid = UUID.fromString(id)
            complete((postActor ? DeletePost(uuid)).map(_ => StatusCodes.OK))
          }
        }
    }
  }

And wrapping the concatenated routes in a cors directive

val routes = cors() {
    concat(categoryRoutes, userRoutes, topicRoutes, postRoutes)
}

My application.conf looks like this:

akka-http-cors {
  allowed-origins = "http://localhost:3000"
  allowed-methods = ["GET", "POST", "PUT", "DELETE"]
}

The full source code is available in this repo

If anyone can suggest where I’ve gone wrong, I’d be very grateful.

1 Like

Is it possible the 400 Bad Request issue means you are not passing through the cors directive on the server side? akka-http-cors/CorsServer.scala at master · lomigmegard/akka-http-cors · GitHub has an example where the handleError directive wraps the cors directive to ensure that even error responses get CORS headers in responses.

1 Like

I’ve looked at your config and compared with mine… you have

akka-http-cors {
  allowed-origins = "http://localhost:3000"
  allowed-headers = "*"
  allowed-methods = ["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS"]
}

while I have

akka-http-cors {
  allowed-origins = ["http://127.0.0.1:1234", "http://localhost:1234"]
  allowed-methods = ["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS"]
  exposed-headers = ["X-Correlation-ID"]
}

what I can spot is that allowed-origins is a list in my code and a string in yours.

This might have been the problem.

I’ve now wrapped the concatenated routes in an error handler and the CORS directive so any error response should also receive the appropriate headers.