Add token renewal backend

This commit is contained in:
2020-04-26 00:49:42 +02:00
parent 9d1d1b3afb
commit 8061c15b04
10 changed files with 114 additions and 62 deletions
+70
View File
@@ -0,0 +1,70 @@
package be.vandewalleh.routing
import be.vandewalleh.auth.SimpleJWT
import be.vandewalleh.auth.UsernamePasswordCredential
import be.vandewalleh.extensions.respondStatus
import be.vandewalleh.services.UserService
import com.auth0.jwt.exceptions.JWTVerificationException
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.http.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
import org.mindrot.jbcrypt.BCrypt
data class RefreshToken(val refreshToken: String)
data class DualToken(val token: String, val refreshToken: String)
fun Routing.auth(kodein: Kodein) {
val authSimpleJwt by kodein.instance<SimpleJWT>("auth")
val refreshSimpleJwt by kodein.instance<SimpleJWT>("refresh")
val userService by kodein.instance<UserService>()
post("/user/login") {
val credential = call.receive<UsernamePasswordCredential>()
val (email, password) = userService.getEmailAndPasswordFromUsername(credential.username)
?: return@post call.respondStatus(HttpStatusCode.Unauthorized)
if (!BCrypt.checkpw(credential.password, password)) {
return@post call.respondStatus(HttpStatusCode.Unauthorized)
}
val response = DualToken(
token = authSimpleJwt.sign(email),
refreshToken = refreshSimpleJwt.sign(email)
)
return@post call.respond(response)
}
post("/user/refresh_token") {
val token = call.receive<RefreshToken>().refreshToken
val email = try {
val decodedJWT = refreshSimpleJwt.verifier.verify(token)
decodedJWT.getClaim("email").asString()
} catch (e: JWTVerificationException) {
return@post call.respondStatus(HttpStatusCode.Unauthorized)
}
val response = DualToken(
token = authSimpleJwt.sign(email),
refreshToken = refreshSimpleJwt.sign(email)
)
return@post call.respond(response)
}
authenticate {
get("/user/me") {
// retrieve email from token
val email = call.principal<UserIdPrincipal>()!!.name
val info = userService.getUserInfo(email)
if (info != null) call.respond(mapOf("user" to info))
else call.respondStatus(HttpStatusCode.Unauthorized)
}
}
}
-46
View File
@@ -1,46 +0,0 @@
package be.vandewalleh.routing
import be.vandewalleh.auth.SimpleJWT
import be.vandewalleh.auth.UsernamePasswordCredential
import be.vandewalleh.extensions.respondStatus
import be.vandewalleh.services.UserService
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.http.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
import org.mindrot.jbcrypt.BCrypt
fun Routing.login(kodein: Kodein) {
val simpleJwt by kodein.instance<SimpleJWT>()
val userService by kodein.instance<UserService>()
data class TokenResponse(val token: String)
post("/user/login") {
val credential = call.receive<UsernamePasswordCredential>()
val (email, password) = userService.getEmailAndPasswordFromUsername(credential.username)
?: return@post call.respond(HttpStatusCode.Unauthorized)
if (!BCrypt.checkpw(credential.password, password)) {
return@post call.respond(HttpStatusCode.Unauthorized)
}
return@post call.respond(TokenResponse(simpleJwt.sign(email)))
}
authenticate {
get("/user/me") {
// retrieve email from token
val email = call.principal<UserIdPrincipal>()!!.name
val info = userService.getUserInfo(email)
if (info != null) call.respond(mapOf("user" to info))
else call.respondStatus(HttpStatusCode.Unauthorized)
}
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ import org.kodein.di.Kodein
fun Routing.registerRoutes(kodein: Kodein) {
user(kodein)
login(kodein)
auth(kodein)
notes(kodein)
title(kodein)
tags(kodein)
-1
View File
@@ -34,7 +34,6 @@ fun Routing.user(kodein: Kodein) {
}
authenticate {
put {
val user = call.receive<UserDto>()