Skip to content

Instantly share code, notes, and snippets.

@amrfarid140
Created January 23, 2020 12:17
Embed
What would you like to do?
Example Token Manager
package me.amryousef.auth
import com.auth0.jwt.JWT
import com.auth0.jwt.JWTVerifier
import com.auth0.jwt.algorithms.Algorithm
import com.auth0.jwt.interfaces.Payload
import io.ktor.auth.Principal
import me.amryousef.model.TokenType
import me.amryousef.model.User
import me.amryousef.usecase.GetUserByIdUseCase
import java.util.*
import java.util.concurrent.TimeUnit
class JwtTokenManager(private val getUserByIdUseCase: GetUserByIdUseCase) {
private companion object {
private const val secret = "super-secret-stuff"
private const val issuer = "amryousef"
private val refreshTokenValidityInMs = TimeUnit.DAYS.toMillis(7)
private val accessTokenValidityInMs = TimeUnit.HOURS.toMillis(8)
private val algorithm = Algorithm.HMAC512(secret)
private const val ID_CLAIM_KEY = "id"
private const val ROLE_CLAIM_KEY = "role"
private const val AUTHENTICATION_SUBJECT = "Authentication"
private const val REFRESH_SUBJECT = "Refresh"
}
val verifier: JWTVerifier = JWT.require(algorithm).withIssuer(issuer).build()
fun createToken(user: User) =
TokenResult(
accessToken = JWT.create()
.withSubject(AUTHENTICATION_SUBJECT)
.withIssuer(issuer)
.withClaim(ID_CLAIM_KEY, user.id)
.withClaim(ROLE_CLAIM_KEY, user.roles.map { it::class.java.simpleName }.joinToString(", "))
.withExpiresAt(getExpiration(accessTokenValidityInMs))
.sign(algorithm),
refreshToken = JWT.create()
.withSubject(REFRESH_SUBJECT)
.withIssuer(issuer)
.withClaim(ID_CLAIM_KEY, user.id)
.withExpiresAt(getExpiration(refreshTokenValidityInMs))
.sign(algorithm)
)
fun isValidToken(token: Payload): TokenValidity {
if (token.expiresAt.before(Date())) {
return TokenValidity.NotValid
}
return token.claims["id"]?.asInt()?.let {
TokenValidity.Valid(
getUserByIdUseCase.execute(it),
token.subject.toTokenType()
)
} ?: TokenValidity.NotValid
}
@Throws(IllegalArgumentException::class)
private fun String.toTokenType() = when (this) {
AUTHENTICATION_SUBJECT -> TokenType.ACCESS
REFRESH_SUBJECT -> TokenType.REFRESH
else -> throw IllegalArgumentException()
}
private fun getExpiration(validityInMs: Long) = Date(System.currentTimeMillis() + validityInMs)
data class TokenResult(val accessToken: String, val refreshToken: String)
sealed class TokenValidity {
data class Valid(
val user: User,
val tokenType: TokenType
) : TokenValidity(), Principal
object NotValid : TokenValidity()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment