CORS plugin
The CORS plugin manages CORS related headers for you given some configuration such as allowed hosts.
Getting started
You can enable the cors plugin through the config.plugins
part of the config:
- Java
- Kotlin
Javalin.create(config -> {
config.bundledPlugins.enableCors(cors -> {
cors.addRule(it -> {
it.allowHost("example.com", "javalin.io");
});
});
});
Javalin.create { config ->
config.bundledPlugins.enableCors { cors ->
cors.addRule {
it.allowHost("example.com", "javalin.io")
}
}
}
This example would allow the origins https://example.com
and https://javalin.io
.
The default scheme can be changed by setting it: defaultScheme = "http"
, but you can also just specify it with your
allowHost()
call: allowHost("http://example.com")
Allowing any host
Allowing everybody by using can be done with anyHost()
.
anyHost()
adds the special star origin *
, allowing any host from a CORS standpoint. Do note that you can still
deny via other means such as an access manager, but it is recommended to just allow the hosts that you need.
- Java
- Kotlin
Javalin.create(config -> {
config.bundledPlugins.enableCors(cors -> {
cors.addRule(it -> {
it.anyHost();
});
});
});
Javalin.create { config ->
config.bundledPlugins.enableCors { cors ->
cors.addRule {
it.anyHost()
}
}
}
Similar to anyHost()
you can set reflectClientOrigin = true
to reflect back the clients origin instead of the generic
star. This has the same implications as anyHost()
, so it should be considered carefully.
- Java
- Kotlin
Javalin.create(config -> {
config.bundledPlugins.enableCors(cors -> {
cors.addRule(it -> {
it.reflectClientOrigin = true;
});
});
});
Javalin.create { config ->
config.bundledPlugins.enableCors { cors ->
cors.addRule {
it.reflectClientOrigin = true
}
}
}
Subdomain wildcard support
Special support for subdomains is added by allowing a single star as a wildcard.
allowHost("*.example.com")
would allow any subdomain of example.com
to access your resources from a CORS standpoint.
- Java
- Kotlin
Javalin.create(config -> {
config.bundledPlugins.enableCors(cors -> {
cors.addRule(it -> {
it.allowHost("*.example.com");
});
});
});
Javalin.create { config ->
config.bundledPlugins.enableCors { cors ->
cors.addRule {
it.allowHost("*.example.com")
}
}
}
Multiple CORS configurations
It is also possible to have different cors configurations for different paths. Take a look at the following example:
- Java
- Kotlin
Javalin.create(config -> {
config.bundledPlugins.enableCors(cors -> {
cors.addRule(it -> {
it.path = "images*";
it.allowHost("https://images.local");
});
cors.addRule(it -> {
it.path = "videos*";
it.allowHost("https://videos.local");
});
cors.addRule(it -> {
it.path = "music*";
it.allowHost("https://music.local");
});
});
});
Javalin.create { config ->
config.bundledPlugins.enableCors { cors ->
cors.addRule {
it.path = "images*"
it.allowHost("https://images.local")
}
cors.addRule {
it.path = "videos*"
it.allowHost("https://videos.local")
}
cors.addRule {
it.path = "music*"
it.allowHost("https://music.local")
}
}
}
Everything listed under images
would be only accessible by the host images.local
and everything under videos
only to the host videos.local
.
allowCredentials and exposeHeader
For those who need it you can also set the Access-Control-Allow-Credentials
header by setting allowCredentials = true
and expose headers to the website’s JavaScript by using e.g. exposeHeader("x-server")
to expose the x-server
header.
- Java
- Kotlin
Javalin.create(config -> {
config.bundledPlugins.enableCors(cors -> {
cors.addRule(it -> {
it.allowHost("*.example.com");
it.allowCredentials = true;
it.exposeHeader("x-server");
});
});
});
Javalin.create { config ->
config.bundledPlugins.enableCors { cors ->
cors.addRule {
it.allowHost("*.example.com")
it.allowCredentials = true
it.exposeHeader("x-server")
}
}
}
Do note that you cannot use Javalin’s anyHost()
option together with Access-Control-Allow-Credentials
as that is
explicitly forbidden by all browsers.
Passing credentials from the frontend to the backend
Browsers do not automatically pass credentials to a backend which sets the Access-Control-Allow-Credentials
.
This must be done explicitly for JavaScript based requests. The following two examples demonstrate this for the browser
native fetch and for the popular axios library.
Minimal example using the fetch
API:
const data = {};
fetch("https://example.com", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
Source: Mozilla’s MDN Using the fetch API
Example using axios
:
import axios from "axios";
const data = {};
axios.post("https://example.com", data, {
withCredentials: true
});
Source: axios request config page