diff --git a/app/src/main/kotlin/controllers/UserController.kt b/app/src/main/kotlin/controllers/UserController.kt index 2c13b0b..6ccdc26 100644 --- a/app/src/main/kotlin/controllers/UserController.kt +++ b/app/src/main/kotlin/controllers/UserController.kt @@ -97,8 +97,8 @@ class UserController( return this.cookie( Cookie( - name = "Authorization", - value = "Bearer $token", + name = "Bearer", + value = token, path = "/", httpOnly = true, sameSite = SameSite.Lax, @@ -109,5 +109,5 @@ class UserController( } fun logout(@Suppress("UNUSED_PARAMETER") request: Request) = Response.redirect("/") - .invalidateCookie("Authorization") + .invalidateCookie("Bearer") } diff --git a/app/src/main/kotlin/filters/AuthFilter.kt b/app/src/main/kotlin/filters/AuthFilter.kt index fcfbf66..2223741 100644 --- a/app/src/main/kotlin/filters/AuthFilter.kt +++ b/app/src/main/kotlin/filters/AuthFilter.kt @@ -37,9 +37,6 @@ class AuthFilter( fun Request.jwtPayload(ctx: RequestContexts): JwtPayload? = ctx[this][authKey] -private fun Request.bearerToken(): String? = cookie("Authorization") +private fun Request.bearerToken(): String? = cookie("Bearer") ?.value ?.trim() - ?.takeIf { it.startsWith("Bearer") } - ?.substringAfter("Bearer") - ?.trim() diff --git a/app/src/test/kotlin/filters/AuthFilterTest.kt b/app/src/test/kotlin/filters/AuthFilterTest.kt index ec2cb95..edf5f16 100644 --- a/app/src/test/kotlin/filters/AuthFilterTest.kt +++ b/app/src/test/kotlin/filters/AuthFilterTest.kt @@ -51,7 +51,7 @@ internal class AuthFilterTest { @Test fun `it should allow an invalid token`() { - val response = app(Request(GET, "/optional").cookie("Authorization", "Bearer nnkjnkjnk")) + val response = app(Request(GET, "/optional").cookie("Bearer", "nnkjnkjnk")) assertThat(response, hasStatus(OK)) assertThat(response, hasBody("null")) } @@ -60,7 +60,7 @@ internal class AuthFilterTest { fun `it should allow a valid token`() { val jwtPayload = JwtPayload(1, "user") val token = simpleJwt.sign(jwtPayload) - val response = app(Request(GET, "/optional").cookie("Authorization", "Bearer $token")) + val response = app(Request(GET, "/optional").cookie("Bearer", token)) assertThat(response, hasStatus(OK)) assertThat(response, hasBody("$jwtPayload")) } @@ -77,7 +77,7 @@ internal class AuthFilterTest { @Test fun `it shouldn't allow an invalid token`() { - val response = app(Request(GET, "/protected").cookie("Authorization", "Bearer nnkjnkjnk")) + val response = app(Request(GET, "/protected").cookie("Bearer", "nnkjnkjnk")) assertThat(response, hasStatus(FOUND)) assertThat(response, hasHeader("Location")) } @@ -86,7 +86,7 @@ internal class AuthFilterTest { fun `it should allow a valid token"`() { val jwtPayload = JwtPayload(1, "user") val token = simpleJwt.sign(jwtPayload) - val response = app(Request(GET, "/protected").cookie("Authorization", "Bearer $token")) + val response = app(Request(GET, "/protected").cookie("Bearer", token)) assertThat(response, hasStatus(OK)) assertThat(response, hasBody("$jwtPayload")) } diff --git a/domain/src/main/kotlin/security/JwtPayload.kt b/domain/src/main/kotlin/security/JwtPayload.kt index 63f89c2..62e939f 100644 --- a/domain/src/main/kotlin/security/JwtPayload.kt +++ b/domain/src/main/kotlin/security/JwtPayload.kt @@ -10,8 +10,8 @@ data class JwtPayload(val userId: Int, val username: String) { class JwtPayloadExtractor(private val jwt: SimpleJwt) { operator fun invoke(token: String): JwtPayload? = try { val decodedJWT = jwt.verifier.verify(token) - val id = decodedJWT.getClaim("id").asInt() ?: null - val username = decodedJWT.getClaim("username").asString() ?: null + val id = decodedJWT.getClaim(userIdField).asInt() ?: null + val username = decodedJWT.getClaim(usernameField).asString() ?: null id?.let { username?.let { JwtPayload(id, username) } } } catch (e: JWTVerificationException) { null diff --git a/domain/src/main/kotlin/security/SimpleJwt.kt b/domain/src/main/kotlin/security/SimpleJwt.kt index d0f4b21..fc4eb99 100644 --- a/domain/src/main/kotlin/security/SimpleJwt.kt +++ b/domain/src/main/kotlin/security/SimpleJwt.kt @@ -7,14 +7,17 @@ import com.auth0.jwt.algorithms.Algorithm import java.util.* import java.util.concurrent.TimeUnit +internal const val userIdField = "i" +internal const val usernameField = "u" + class SimpleJwt(jwtConfig: JwtConfig) { private val validityInMs = TimeUnit.MILLISECONDS.convert(jwtConfig.validity, jwtConfig.timeUnit) private val algorithm = Algorithm.HMAC256(jwtConfig.secret) val verifier: JWTVerifier = JWT.require(algorithm).build() fun sign(jwtPayload: JwtPayload): String = JWT.create() - .withClaim("id", jwtPayload.userId) - .withClaim("username", jwtPayload.username) + .withClaim(userIdField, jwtPayload.userId) + .withClaim(usernameField, jwtPayload.username) .withExpiresAt(getExpiration()) .sign(algorithm) diff --git a/domain/src/test/kotlin/security/JwtPayloadExtractorTest.kt b/domain/src/test/kotlin/security/JwtPayloadExtractorTest.kt index ed00276..6608696 100644 --- a/domain/src/test/kotlin/security/JwtPayloadExtractorTest.kt +++ b/domain/src/test/kotlin/security/JwtPayloadExtractorTest.kt @@ -21,8 +21,8 @@ internal class JwtPayloadExtractorTest { private fun createToken(username: String? = null, id: Int? = null, secret: String = jwtConfig.secret): Token { val algo = Algorithm.HMAC256(secret) return JWT.create().apply { - username?.let { withClaim("username", it) } - id?.let { withClaim("id", it) } + username?.let { withClaim(usernameField, it) } + id?.let { withClaim(userIdField, it) } }.sign(algo) }