-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6dc7d53
commit 39addf5
Showing
33 changed files
with
763 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,30 @@ | ||
-- scheme | ||
CREATE | ||
DATABASE hero CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; | ||
|
||
-- 유저 정보 | ||
CREATE TABLE `user_info` | ||
( | ||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'user id', | ||
`nickname` varchar(64) NOT NULL COMMENT '닉네임', | ||
`created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '생성일', | ||
`modified_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '수정일', | ||
PRIMARY KEY (`id`) | ||
) ENGINE=InnoDB AUTO_INCREMENT=200000 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='유저 정보'; | ||
|
||
CREATE UNIQUE INDEX uidx__nickname ON user_info (nickname); | ||
|
||
-- 일반 회원가입 유저 정보 | ||
CREATE TABLE `credential_user_info` | ||
( | ||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'credential_user_info id', | ||
`uid` bigint NOT NULL COMMENT 'user id', | ||
`username` varchar(256) NOT NULL COMMENT '로그인 id', | ||
`password` varchar(512) NOT NULL COMMENT '로그인 pw', | ||
`created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '생성일', | ||
`modified_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '수정일', | ||
PRIMARY KEY (`id`) | ||
) ENGINE=InnoDB AUTO_INCREMENT=200000 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='유저 정보'; | ||
|
||
CREATE UNIQUE INDEX uidx__uid ON credential_user_info (uid); | ||
CREATE UNIQUE INDEX uidx__username ON credential_user_info (username); |
17 changes: 17 additions & 0 deletions
17
src/main/kotlin/com/hero/alignlab/common/encrypt/EncryptData.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.hero.alignlab.common.encrypt | ||
|
||
data class EncryptData( | ||
val encData: String, | ||
) { | ||
fun dec(encryptor: Encryptor): String { | ||
return encryptor.decrypt(this.encData) | ||
} | ||
|
||
companion object { | ||
fun enc(plainData: String, encryptor: Encryptor): EncryptData { | ||
return EncryptData( | ||
encData = encryptor.encrypt(plainData) | ||
) | ||
} | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/kotlin/com/hero/alignlab/common/encrypt/Encryptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.hero.alignlab.common.encrypt | ||
|
||
import java.util.* | ||
import javax.crypto.Cipher | ||
import javax.crypto.spec.IvParameterSpec | ||
import javax.crypto.spec.SecretKeySpec | ||
|
||
data class Encryptor( | ||
private val key: String, | ||
private val algorithm: String, | ||
) { | ||
fun encrypt(text: String): String { | ||
val cipher = Cipher.ENCRYPT_MODE.cipher() | ||
val encrypted = cipher.doFinal(text.toByteArray(charset(Charsets.UTF_8.name()))) | ||
|
||
return Base64.getEncoder().encodeToString(encrypted) | ||
} | ||
|
||
fun decrypt(text: String): String { | ||
val cipher = Cipher.DECRYPT_MODE.cipher() | ||
val decodedBytes = Base64.getDecoder().decode(text) | ||
val decrypted = cipher.doFinal(decodedBytes) | ||
|
||
return String(decrypted, Charsets.UTF_8) | ||
} | ||
|
||
private fun Int.cipher(): Cipher { | ||
val cipher = Cipher.getInstance(algorithm) | ||
val keySpec = SecretKeySpec(key.toByteArray(), "AES") | ||
val ivParamSpec = IvParameterSpec(key.toByteArray()) | ||
|
||
cipher.init(this, keySpec, ivParamSpec) | ||
|
||
return cipher | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.hero.alignlab.config | ||
|
||
import com.hero.alignlab.common.encrypt.Encryptor | ||
import io.github.oshai.kotlinlogging.KotlinLogging | ||
import org.springframework.boot.context.properties.ConfigurationProperties | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Configuration | ||
|
||
@Configuration | ||
@EnableConfigurationProperties(EncryptConfig.EncryptProperty::class) | ||
class EncryptConfig { | ||
private val logger = KotlinLogging.logger {} | ||
|
||
@ConfigurationProperties(prefix = "encrypt") | ||
data class EncryptProperty( | ||
val key: String, | ||
val algorithm: String, | ||
) | ||
|
||
@Bean | ||
fun encryptor( | ||
property: EncryptProperty, | ||
): Encryptor { | ||
logger.info { "initialized encryptor. key: ${property.key} algorithm: ${property.algorithm}" } | ||
return Encryptor(property.key, property.algorithm) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.hero.alignlab.config | ||
|
||
import jakarta.validation.constraints.NotBlank | ||
import org.springframework.boot.context.properties.ConfigurationProperties | ||
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding | ||
import org.springframework.context.annotation.Configuration | ||
|
||
@Configuration | ||
@ConfigurationProperties(prefix = "auth.jwt") | ||
@ConfigurationPropertiesBinding | ||
data class JwtConfig( | ||
@field:NotBlank | ||
var secret: String = "", | ||
@field:NotBlank | ||
var accessExp: Int = 0, | ||
@field:NotBlank | ||
var refreshExp: Int = 0, | ||
val issuer: String = "hero-alignlab-api", | ||
val audience: String = "hero-alignlab-api", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
src/main/kotlin/com/hero/alignlab/domain/auth/application/AuthFacade.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package com.hero.alignlab.domain.auth.application | ||
|
||
import com.hero.alignlab.common.encrypt.EncryptData | ||
import com.hero.alignlab.common.encrypt.Encryptor | ||
import com.hero.alignlab.config.database.TransactionTemplates | ||
import com.hero.alignlab.domain.auth.model.AuthContextImpl | ||
import com.hero.alignlab.domain.auth.model.AuthUserImpl | ||
import com.hero.alignlab.domain.auth.model.AuthUserToken | ||
import com.hero.alignlab.domain.auth.model.request.SignInRequest | ||
import com.hero.alignlab.domain.auth.model.request.SignUpRequest | ||
import com.hero.alignlab.domain.auth.model.response.SignInResponse | ||
import com.hero.alignlab.domain.auth.model.response.SignUpResponse | ||
import com.hero.alignlab.domain.user.application.CredentialUserInfoService | ||
import com.hero.alignlab.domain.user.application.UserService | ||
import com.hero.alignlab.domain.user.domain.CredentialUserInfo | ||
import com.hero.alignlab.domain.user.domain.UserInfo | ||
import com.hero.alignlab.exception.ErrorCode | ||
import com.hero.alignlab.exception.InvalidRequestException | ||
import com.hero.alignlab.exception.InvalidTokenException | ||
import org.springframework.stereotype.Service | ||
import reactor.core.publisher.Mono | ||
import java.time.LocalDateTime | ||
|
||
@Service | ||
class AuthFacade( | ||
private val userService: UserService, | ||
private val credentialUserInfoService: CredentialUserInfoService, | ||
private val jwtTokenService: JwtTokenService, | ||
private val encryptor: Encryptor, | ||
private val txTemplates: TransactionTemplates, | ||
) { | ||
companion object { | ||
private val TOKEN_EXPIRED_DATE = LocalDateTime.of(2024, 12, 29, 0, 0, 0) | ||
} | ||
|
||
fun resolveAuthUser(token: Mono<AuthUserToken>): Mono<Any> { | ||
return jwtTokenService.verifyTokenMono(token) | ||
.handle { payload, sink -> | ||
if (payload.type != "accessToken") { | ||
sink.error(InvalidTokenException(ErrorCode.INVALID_ACCESS_TOKEN)) | ||
return@handle | ||
} | ||
|
||
val user = userService.getUserByIdOrThrowSync(payload.id) | ||
|
||
sink.next( | ||
AuthUserImpl( | ||
uid = user.id, | ||
context = AuthContextImpl( | ||
name = user.nickname | ||
) | ||
) | ||
) | ||
} | ||
} | ||
|
||
suspend fun signUp(request: SignUpRequest): SignUpResponse { | ||
if (credentialUserInfoService.existsByUsername(request.username)) { | ||
throw InvalidRequestException(ErrorCode.DUPLICATED_USERNAME_ERROR) | ||
} | ||
|
||
val userInfo = userService.save(UserInfo(nickname = request.username)) | ||
|
||
credentialUserInfoService.save( | ||
CredentialUserInfo( | ||
uid = userInfo.id, | ||
username = request.username, | ||
password = EncryptData.enc(request.password, encryptor) | ||
) | ||
) | ||
|
||
return SignUpResponse( | ||
accessToken = jwtTokenService.createToken(userInfo.id, TOKEN_EXPIRED_DATE) | ||
) | ||
} | ||
|
||
suspend fun signIn(request: SignInRequest): SignInResponse { | ||
val credentialUserInfo = credentialUserInfoService.findByUsernameAndPassword(request.username, request.password) | ||
|
||
val user = userService.getUserByIdOrThrowSync(credentialUserInfo.uid) | ||
|
||
return SignInResponse( | ||
accessToken = jwtTokenService.createToken(user.id, TOKEN_EXPIRED_DATE) | ||
) | ||
} | ||
} |
Oops, something went wrong.