Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

[#10] refactor: login service and anything related #15

Open
wants to merge 1 commit into
base: ft/9
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class JwtTokenService(
}

fun reissueToken(tokenSet: TokenSet): TokenSet {
// TODO: 여기 에러 핸들링 필요할 듯 하다. ControllerAdvice 만들어줄 때 함께 처리하자.
parseToken(tokenSet.refreshToken)

val authentication = createAuthenticationToken(parseToken(tokenSet.accessToken))
Expand Down Expand Up @@ -83,11 +82,11 @@ class JwtTokenService(
Jwts.parserBuilder().setSigningKey(prop.key).build().parseClaimsJws(token)
} catch (e: RuntimeException) {
when (e) {
is SignatureException -> { throw SignatureException("서명이 잘못된 토큰입니다.", e) }
is MalformedJwtException -> { throw MalformedJwtException("올바르게 생성된 토큰이 아닙니다.", e) }
is ExpiredJwtException -> { throw ExpiredJwtException(e.header, e.claims, "이미 만료된 토큰입니다.", e) }
is UnsupportedJwtException -> { throw UnsupportedJwtException("지원되지 않는 형식의 토큰입니다.", e) }
else -> { throw IllegalArgumentException("토큰이 입력되지 않았습니다.", e) }
is SignatureException -> throw SignatureException("서명이 잘못된 토큰입니다.", e)
is MalformedJwtException -> throw MalformedJwtException("올바르게 생성된 토큰이 아닙니다.", e)
is ExpiredJwtException -> throw ExpiredJwtException(e.header, e.claims, "이미 만료된 토큰입니다.", e)
is UnsupportedJwtException -> throw UnsupportedJwtException("지원되지 않는 형식의 토큰입니다.", e)
else -> throw IllegalArgumentException("토큰이 입력되지 않았습니다.", e)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ class SecurityConfig(
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/**/sign-up").permitAll()
.antMatchers("/customers/login").permitAll()
.antMatchers("/members/common/my-info").hasAuthority("MEMBER")
.anyRequest().authenticated()
.anyRequest().permitAll()
// .antMatchers("/**/sign-up").permitAll()
// .antMatchers("/customers/login").permitAll()
// .antMatchers("/members/common/my-info").hasAuthority("MEMBER")
// .anyRequest().authenticated()
.and()
.apply(JwtSecurityConfig(tokenService))
}
Expand Down
42 changes: 0 additions & 42 deletions src/main/kotlin/com/kotlin/delivery/common/entity/Member.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.kotlin.delivery.member.common

import com.kotlin.delivery.member.common.dto.LoginRequest
import com.kotlin.delivery.member.common.service.LoginService
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/members/common")
class MemberLoginController(private val loginService: LoginService) {

@PostMapping("/login")
fun login(@RequestBody req: LoginRequest) = loginService.login(req)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.kotlin.delivery.common.entity
package com.kotlin.delivery.member.common.entity

import javax.persistence.Column
import javax.persistence.Embeddable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.kotlin.delivery.common.entity
package com.kotlin.delivery.member.common.entity

import javax.persistence.Embeddable

Expand Down
23 changes: 23 additions & 0 deletions src/main/kotlin/com/kotlin/delivery/member/common/entity/Member.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.kotlin.delivery.member.common.entity

import com.kotlin.delivery.common.entity.MutableEntity
import com.kotlin.delivery.member.common.dto.SignUpRequest
import com.kotlin.delivery.member.common.util.MemberStatus
import javax.persistence.Column
import javax.persistence.EnumType
import javax.persistence.Enumerated
import javax.persistence.MappedSuperclass

@MappedSuperclass
class Member(

@Column(nullable = false)
var nickname: String,

@Column(nullable = false)
val mobile: String,

@Column(nullable = false)
@Enumerated(EnumType.STRING)
var status: MemberStatus = MemberStatus.ACTIVE,
) : MutableEntity()
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.kotlin.delivery.member.common.entity

import com.kotlin.delivery.common.entity.MutableEntity
import com.kotlin.delivery.member.common.util.MemberType
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated
import javax.persistence.Table

@Entity
@Table(name = "member_summary")
class MemberSummary(

@Column(nullable = false, unique = true)
var email: String,

@Column(nullable = false)
var password: String,

@Column(nullable = false)
@Enumerated(EnumType.STRING)
var type: MemberType
) : MutableEntity()
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package com.kotlin.delivery.member.common.repository

import com.kotlin.delivery.common.entity.Member
import com.kotlin.delivery.member.common.dto.LoginResponse
import com.kotlin.delivery.member.common.entity.Member
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.repository.NoRepositoryBean

@NoRepositoryBean
interface MemberRepository<T : Member, ID> : JpaRepository<T, ID> {

fun findByEmail(email: String): LoginResponse?

fun existsByEmail(email: String): Boolean
}
interface MemberRepository<T : Member, ID> : JpaRepository<T, ID>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.kotlin.delivery.member.common.repository

import com.kotlin.delivery.member.common.dto.LoginResponse
import com.kotlin.delivery.member.common.entity.MemberSummary
import org.springframework.data.jpa.repository.JpaRepository

interface MemberSummaryRepository : JpaRepository<MemberSummary, Long> {

fun existsByEmail(email: String): Boolean

fun findByEmail(email: String): LoginResponse?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.kotlin.delivery.member.common.service

import com.kotlin.delivery.member.common.dto.LoginResponse
import com.kotlin.delivery.member.common.repository.MemberSummaryRepository
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.User
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.stereotype.Service

@Service
class MemberDetailsService(private val memberSummaryRepository: MemberSummaryRepository) : UserDetailsService {

override fun loadUserByUsername(email: String): UserDetails =
memberSummaryRepository.findByEmail(email)?.let { createUserDetails(it) }
?: throw UsernameNotFoundException("사용자 정보가 일치하지 않습니다. 입력하신 정보를 다시 한 번 확인해주세요.")

private fun createUserDetails(res: LoginResponse): User {
val grantedAuthority = SimpleGrantedAuthority(res.getType().toString())
return User(res.getEmail(), res.getPassword(), setOf(grantedAuthority))
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
package com.kotlin.delivery.member.common.service

import com.kotlin.delivery.common.entity.Member
import com.kotlin.delivery.member.common.entity.Member
import com.kotlin.delivery.member.common.dto.SignUpRequest
import com.kotlin.delivery.member.common.entity.MemberSummary
import com.kotlin.delivery.member.common.util.MemberType
import com.kotlin.delivery.member.common.repository.MemberRepository
import com.kotlin.delivery.member.common.repository.MemberSummaryRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.dao.DuplicateKeyException
import org.springframework.security.crypto.password.PasswordEncoder
import kotlin.reflect.KClass

abstract class AbstractSignUpService<T : Member, R : MemberRepository<T, Long>> {
abstract class MemberService<T : Member, R : MemberRepository<T, Long>> {

@Autowired
lateinit var passwordEncoder: PasswordEncoder

@Autowired
lateinit var memberSummaryRepository: MemberSummaryRepository
/**
* 공통 회원가입을 처리하는 메소드
* 회원 종류(Customer, Rider, Owner)에 상관 없이 공통 포맷을 가지고 최소한의 중복으로 회원가입을 처리하기 위해 노력...
* 1. 회원 종류에 맞는 repository 를 결정한다.
* 2. 회원 종류에 맞는 entity 를 생성한다.
*/
fun signUp(req: SignUpRequest, type: MemberType, repositoryClass: KClass<R>) {
val repository = decideRepository(repositoryClass)
if (repository.existsByEmail(req.email)) {
if (memberSummaryRepository.existsByEmail(req.email)) {
throw DuplicateKeyException("동일한 이메일로 가입된 사용자가 이미 존재합니다.")
}

val common = Member(req, passwordEncoder.encode(req.password), type)
val entity = createTypeEntity(common)
repository.save(entity)
val memberRepository = decideRepository(repositoryClass)
val summary = memberSummaryRepository.save(MemberSummary(req.email, passwordEncoder.encode(req.password), type))
val common = Member(req.nickname, req.mobile)
val member = createTypeEntity(summary, common)
memberRepository.save(member)
}

abstract fun decideRepository(repositoryClass: KClass<R>): R

abstract fun createTypeEntity(common: Member): T
abstract fun createTypeEntity(summary: MemberSummary, common: Member): T
}
10 changes: 0 additions & 10 deletions src/main/kotlin/com/kotlin/delivery/member/common/util/Utils.kt

This file was deleted.

22 changes: 12 additions & 10 deletions src/main/kotlin/com/kotlin/delivery/member/customer/Customer.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
package com.kotlin.delivery.member.customer

import com.kotlin.delivery.common.entity.Location
import com.kotlin.delivery.common.entity.Member
import com.kotlin.delivery.common.entity.Image
import com.kotlin.delivery.member.common.entity.Location
import com.kotlin.delivery.member.common.entity.Member
import com.kotlin.delivery.member.common.entity.Image
import com.kotlin.delivery.member.common.entity.MemberSummary
import javax.persistence.Embedded
import javax.persistence.Entity
import javax.persistence.FetchType
import javax.persistence.JoinColumn
import javax.persistence.OneToOne
import javax.persistence.Table

@Entity
@Table(name = "customers")
class Customer(

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "summary_id", nullable = false)
val summary: MemberSummary,

common: Member,

@Embedded
val location: Location? = null,

@Embedded
val profileImage: Image? = null,
) : Member(
email = common.email,
password = common.password,
nickname = common.nickname,
mobile = common.mobile,
type = common.type
) {
) : Member(nickname = common.nickname, mobile = common.mobile) {

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.kotlin.delivery.member.customer

import com.kotlin.delivery.common.config.BeanConfig
import com.kotlin.delivery.member.common.entity.Member
import com.kotlin.delivery.member.common.entity.MemberSummary
import com.kotlin.delivery.member.common.service.MemberService
import org.springframework.stereotype.Service
import kotlin.reflect.KClass

@Service
class CustomerSignupService(val beanConfig: BeanConfig) : MemberService<Customer, CustomerRepository>() {

override fun decideRepository(repositoryClass: KClass<CustomerRepository>) = beanConfig.getBean(repositoryClass)

override fun createTypeEntity(summary: MemberSummary, common: Member) = Customer(summary, common)
}

This file was deleted.

Loading