Setting cookies on redirect
First, I will set a cookie value on redirect.
I created two micronaut applications.
When a user access the application1, it redirects to application2 and set a cookie.
[Application1] HomeController.java
package jp.masanori;
import java.util.Optional;
import java.net.URI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MutableHttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.cookie.Cookie;
import io.micronaut.http.cookie.Cookies;
import io.micronaut.http.cookie.SameSite;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.annotation.CookieValue;
@Controller("/")
public class HomeController {
private final Logger logger;
public HomeController() {
this.logger = LoggerFactory.getLogger(HomeController.class);
}
@Get("/")
public String index(@CookieValue("SESSION-VALUE") Optional<String> sessionValue,
HttpRequest<String> req) {
if (sessionValue.isPresent()) {
logger.debug("OK: " + sessionValue.get());
} else {
logger.debug("No cookie");
}
Cookies c = req.getCookies();
for (var v : c.getAll()) {
logger.debug("--------Cookie---------");
logger.debug("Name:" + v.getName());
logger.debug("Value: " + v.getValue());
logger.debug("Domain:" + v.getDomain());
logger.debug("Path: " + v.getPath());
logger.debug("MaxAge: " + v.getMaxAge());
logger.debug("SameSite: " + v.getSameSite());
logger.debug("HttpOnly: " + v.isHttpOnly());
logger.debug("Secure: " + v.isSecure());
}
return "Hello World!";
}
@Get("/redirect")
public MutableHttpResponse<Object> redirectToOutTasks() {
URI location = URI.create("http://ourtasks.masanori.jp:8083/ourtasks/pages/cookie");
Cookie ck = Cookie.of("SESSION-VALUE", "Hello Micronaut!");
return HttpResponse.redirect(location)
.cookie(ck);
}
}
[Application2] PageController.java
package jp.masanori.apps;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.CookieValue;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.micronaut.views.View;
@Controller("/pages")
public class PageController {
private final Logger logger;
public PageController() {
this.logger = LoggerFactory.getLogger(PageController.class);
}
@Produces(MediaType.TEXT_HTML)
@Get("/cookie")
@View("editTask")
public HttpResponse<String> getCookieSample(@CookieValue("SESSION-VALUE") Optional<String> sessionValue) {
if (sessionValue.isPresent()) {
logger.debug("OK: " + sessionValue.get());
} else {
logger.debug("No cookie");
}
return HttpResponse.ok();
}
}
Set cookies into subdomains
By defaut, the application2 can't get the cookie value.
When I access sample.masanori.jp:8086(HomeController.index() of application1 is called),
I will get logs like below.
--------Cookie---------
Name:SESSION-VALUE
Value: Hello Micronaut!
Domain:null
Path: null
MaxAge: -9223372036854775808
SameSite: Optional.empty
HttpOnly: false
Secure: false
Because their domains are just added into the hosts file of Windows,
so if I change the application1 domain into "ourtasks.masanori.jp:8086", the application2 can get the cookie value.
hosts
...
127.0.0.1 ourtasks.masanori.jp
127.0.0.1 sample.masanori.jp
To share cookie values between their domains, I will add some options.
[Application1] HomeController.java
...
@Get("/redirect")
public MutableHttpResponse<Object> redirectToOutTasks() {
URI location = URI.create("http://ourtasks.masanori.jp:8083/ourtasks/pages/cookie");
Cookie ck = Cookie.of("SESSION-VALUE", "Hello Micronaut!!");
// To avoid accessing the cookie value from the client-side
ck.httpOnly(true);
// Share the cookie value on "masanori.jp" or "*.masanori.jp".
// Both the application1 and application2 have to belong to these domains.
ck.domain("masanori.jp");
ck.sameSite(SameSite.Strict);
return HttpResponse.redirect(location)
.cookie(ck);
}
}
Set cookies for Undertow
When I use Under tow as a web server, the above code could not set cookies.
(Although I can see the value on a web browser, but I could not get it on my application)
So I should add "Set-Cookie" into the HttpResponse headers.
build.gradle
...
micronaut {
runtime("undertow")
testRuntime("junit5")
processing {
incremental(true)
annotations("jp.masanori.*")
}
aot {
...
}
}
...
PageController.java
...
@Get("/jwt")
public MutableHttpResponse<?> tryJwt(@CookieValue("JWT-VALUE") Optional<String> sessionValue) {
if (sessionValue.isPresent()) {
logger.info("OK: " + sessionValue.get());
return HttpResponse.ok();
} else {
return HttpResponse.ok()
// I could not use "cookie()" for Undertow
/* .cookie(ck) */
.header("Set-Cookie", String.format("JWT-VALUE=%s;path=/;HttpOnly;", "Hello"));
}
}
...
Set JWT to cookies
I will try setting JWT as a cookie value using java-jwt.
PageController.java
import java.util.Date;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import io.micronaut.core.util.CollectionUtils;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.CookieValue;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.micronaut.views.View;
import io.micronaut.http.cookie.Cookies;
@Controller("/pages")
public class PageController {
...
@Get("/jwt")
public MutableHttpResponse<?> tryJwt(@CookieValue("JWT-VALUE") Optional<String> sessionValue) {
if (sessionValue.isPresent()) {
if (validateJwt(sessionValue)) {
return HttpResponse.ok();
} else {
return HttpResponse.unauthorized();
}
} else {
return HttpResponse.ok()
/* .cookie(ck) */
.header("Set-Cookie", String.format("JWT-VALUE=%s;path=/;HttpOnly;", generateJwt()));
}
}
private String generateJwt() {
try {
Date expireTime = new Date();
expireTime.setTime(expireTime.getTime() + 10000);
Algorithm algorithm = Algorithm.HMAC256("secret");
return JWT.create()
.withClaim("message", "hello")
.withIssuer("masanori")
.withExpiresAt(expireTime)
.sign(algorithm);
} catch (JWTCreationException exception) {
logger.error("JWT Error: ", exception);
}
return null;
}
private boolean validateJwt(Optional<String> value) {
if (value.isPresent() == false) {
return false;
}
try {
Algorithm algorithm = Algorithm.HMAC256("secret");
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("masanori")
.build();
DecodedJWT jwt = verifier.verify(value.get());
Claim message = jwt.getClaim("message");
if (message.isMissing() == false && message.isNull() == false) {
logger.info("decoded message: " + message.asString());
}
return true;
} catch (JWTVerificationException exception) {
logger.error("JWT validate failed ", exception);
return false;
}
}
...
Top comments (0)