add gigawear auth repository
This commit is contained in:
@@ -4,7 +4,6 @@ import com.auth0.jwt.JWT
|
||||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import org.koin.core.annotation.Single
|
||||
import ru.shadowsparky.backend.domain.JwtInfo
|
||||
import ru.shadowsparky.backend.domain.LOGIN_NAME
|
||||
import ru.shadowsparky.backend.domain.USER_ID_ARG
|
||||
import java.util.Date
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -15,15 +14,11 @@ class JwtPreparer(
|
||||
private val envFetcher: EnvFetcher
|
||||
) {
|
||||
private val tokenTimeInMinutes = envFetcher.get("JWT_DURATION", "30").toLong()
|
||||
fun prepare(
|
||||
login: String,
|
||||
userId: Long
|
||||
): String {
|
||||
fun prepare(userId: Long): String {
|
||||
val exp = Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(tokenTimeInMinutes))
|
||||
val token = JWT.create()
|
||||
.withAudience(jwtInfo.audience)
|
||||
.withIssuer(jwtInfo.issuer)
|
||||
.withClaim(LOGIN_NAME, login)
|
||||
.withClaim(USER_ID_ARG, userId)
|
||||
.withSubject(userId.toString())
|
||||
.withExpiresAt(exp)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package ru.shadowsparky.backend.data
|
||||
|
||||
import java.security.MessageDigest
|
||||
import java.security.SecureRandom
|
||||
import kotlin.io.encoding.Base64
|
||||
|
||||
fun generateRefreshToken(): String {
|
||||
val refresh = ByteArray(32)
|
||||
SecureRandom().nextBytes(refresh)
|
||||
return refresh.toHexString()
|
||||
}
|
||||
|
||||
fun String.toTokenHash(salt: String): String {
|
||||
val md = MessageDigest.getInstance("SHA-256")
|
||||
md.update(salt.toByteArray())
|
||||
val result = md.digest(this.toByteArray())
|
||||
return Base64.encode(result)
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import com.auth0.jwt.algorithms.Algorithm
|
||||
import com.auth0.jwt.interfaces.DecodedJWT
|
||||
import org.koin.core.annotation.Factory
|
||||
import ru.shadowsparky.backend.domain.JwtInfo
|
||||
import ru.shadowsparky.backend.domain.LOGIN_NAME
|
||||
import ru.shadowsparky.backend.domain.LoginVerifier
|
||||
import ru.shadowsparky.backend.domain.USER_ID_ARG
|
||||
|
||||
@Factory
|
||||
class TokenVerifier(
|
||||
@@ -22,7 +22,7 @@ class TokenVerifier(
|
||||
|
||||
suspend fun verify(token: String): DecodedJWT {
|
||||
val jwt = verifier.verify(token)
|
||||
loginVerifier.verify(jwt.getClaim(LOGIN_NAME).asString())
|
||||
loginVerifier.verify(jwt.getClaim(USER_ID_ARG).asLong())
|
||||
return jwt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package ru.shadowsparky.backend.domain
|
||||
|
||||
interface LoginVerifier {
|
||||
suspend fun verify(login: String)
|
||||
suspend fun verify(userId: Long)
|
||||
}
|
||||
|
||||
const val LOGIN_NAME = "login"
|
||||
const val USER_ID_ARG = "user_id"
|
||||
|
||||
const val INVALID_TOKEN_MSG = "Для выполнения этого действия требуется авторизация."
|
||||
|
||||
+3
-4
@@ -16,7 +16,6 @@ import ru.shadowsparky.backend.data.TokenVerifier
|
||||
import ru.shadowsparky.backend.domain.ExceptionInfo
|
||||
import ru.shadowsparky.backend.domain.INVALID_TOKEN_MSG
|
||||
import ru.shadowsparky.backend.domain.JwtInfo
|
||||
import ru.shadowsparky.backend.domain.LOGIN_NAME
|
||||
import ru.shadowsparky.backend.domain.LoginVerifier
|
||||
import ru.shadowsparky.backend.domain.USER_ID_ARG
|
||||
import ru.shadowsparky.backend.domain.VerifyTokenException
|
||||
@@ -44,10 +43,10 @@ fun Application.configureJwt(
|
||||
realm = jwtInfo.realm
|
||||
verifier(tokenVerifier.verifier)
|
||||
validate { credential ->
|
||||
val login = credential.payload.getClaim(LOGIN_NAME).asString()
|
||||
val userId = credential.payload.getClaim(USER_ID_ARG).asLong()
|
||||
try {
|
||||
if (login != null) {
|
||||
loginVerifier.verify(login)
|
||||
if (userId != null) {
|
||||
loginVerifier.verify(userId)
|
||||
if (credential.payload.expiresAt == null) {
|
||||
throw VerifyTokenException("Static tokens not supported!")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user