Skip to content

Instantly share code, notes, and snippets.

@amrfarid140 amrfarid140/TokenManager.Kt Secret
Created Jan 23, 2020

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
You can’t perform that action at this time.