Skip to content

Commit

Permalink
Merge pull request #65 from TinU-Official/issue63/refresh-token-logic…
Browse files Browse the repository at this point in the history
…-feat

Issue63/refresh token logic feat
  • Loading branch information
programofktw authored Dec 17, 2024
2 parents eecde9c + 20d948d commit 4e7e1e1
Show file tree
Hide file tree
Showing 15 changed files with 305 additions and 8 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ dependencies {
implementation "io.jsonwebtoken:jjwt-api:0.11.5"
implementation "io.jsonwebtoken:jjwt-impl:0.11.5"
implementation("io.jsonwebtoken:jjwt-jackson:0.11.5")

//OAuth2 관련 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
}

kotlin {
Expand Down
19 changes: 19 additions & 0 deletions src/main/kotlin/com/tinuproject/tinu/domain/entity/RefreshToken.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.tinuproject.tinu.domain.entity

import com.tinuproject.tinu.domain.entity.base.BaseEntity
import jakarta.persistence.*
import java.util.*

@Entity
class RefreshToken(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id : Long?= null,

@Column(unique = true)
var userId : UUID,

@Column(unique = true)
var token : String
){
}
11 changes: 10 additions & 1 deletion src/main/kotlin/com/tinuproject/tinu/domain/enum/Social.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,14 @@ package com.tinuproject.tinu.domain.enum
enum class Social(var code:Int, var company : String) {
KAKAO(0, "카카오"),
GOOGLE(1, "구글"),
NAVER(2, "네이버")
NAVER(2, "네이버");


companion object{
fun getSocial(provider : String) : Social{
if(provider == "kakao") return KAKAO
else return NAVER
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ package com.tinuproject.tinu.domain.exception.token

import com.tinuproject.tinu.domain.exception.base.BaseException

class InvalidedToken:BaseException(TokenErrorCode.TOKEN_INVALIDED) {
}
class InvalidedToken(

):BaseException(tokenErrorCode=TokenErrorCode.TOKEN_INVALIDED) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.tinuproject.tinu.domain.socialmember.repository

import com.tinuproject.tinu.domain.entity.SocialMember
import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository
import java.util.*

@Repository
interface SocialMemberRepository:CrudRepository<SocialMember, Long> {
fun findByUserId(userId : UUID) : SocialMember?

fun findByProviderId(providerId : String) : SocialMember?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.tinuproject.tinu.domain.socialmember.service

interface SocialMemberService {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.tinuproject.tinu.security

import com.tinuproject.tinu.domain.entity.RefreshToken
import jakarta.persistence.ManyToOne
import jakarta.transaction.Transactional
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository
import java.util.*

@Repository
interface RefreshTokenRepository:CrudRepository<RefreshToken, Long> {

fun findByUserId(userId : UUID) : RefreshToken

@Transactional
@Modifying
fun deleteByUserId(userId : UUID)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.tinuproject.tinu.security.config

import com.tinuproject.tinu.security.filter.JwtTokenFilter
import com.tinuproject.tinu.security.jwt.JwtUtil
import com.tinuproject.tinu.security.oauth2.handler.OAuthLoginFailureHandler
import com.tinuproject.tinu.security.oauth2.handler.OAuthLoginSuccessHandler
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.Customizer
Expand All @@ -17,18 +21,22 @@ import org.springframework.security.config.annotation.web.configurers.SessionMan
import org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter

@Configuration
@EnableWebSecurity
class SecurityConfig(
private val jwtUtil: JwtUtil,
private val oauth2LoginSuccessHandler: OAuthLoginSuccessHandler,
private val oAuthLoginFailureHandler: OAuthLoginFailureHandler
) {

@Bean
fun configure(): WebSecurityCustomizer? {
return WebSecurityCustomizer { web: WebSecurity ->
//로그인이 아예 안되어 있어도 괜찮은 api
//해당 ""에 API 추가시 해당 API는 필터를 거치지 않음.
web.ignoring().requestMatchers("")
// web.ignoring().requestMatchers("")
}
}

Expand Down Expand Up @@ -61,15 +69,15 @@ class SecurityConfig(
Customizer { authorize ->
authorize
//TODO(배포 전 로그인 되어 있어야만 서비스 이용가능하게 변경)
.requestMatchers("/**").permitAll()//로그인 여부 상관없이 적용
.requestMatchers("/**").authenticated()
// .requestMatchers("/**").permitAll()//로그인 여부 상관없이 적용
.anyRequest().authenticated()//로그인 이후엔 모두 허용
}
)
.oauth2Login { oauth: OAuth2LoginConfigurer<HttpSecurity?> -> // OAuth2 로그인 기능에 대한 여러 설정의 진입점
oauth
//TODO(핸들러 제작 이후 추가)
//.successHandler() // 로그인 성공 시 핸들러
//.failureHandler() // 로그인 실패 시 핸들러
.successHandler(oauth2LoginSuccessHandler) // 로그인 성공 시 핸들러
.failureHandler(oAuthLoginFailureHandler) // 로그인 실패 시 핸들러
}
.sessionManagement {
Customizer { session: SessionManagementConfigurer<HttpSecurity?> ->
Expand All @@ -78,6 +86,8 @@ class SecurityConfig(
}
}
//TODO(이후 FILTER 제작 이후 추가)
// httpSecurity
// .addFilterBefore(JwtTokenFilter(jwtUtil), UsernamePasswordAuthenticationFilter::class.java)

return httpSecurity.build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class JwtTokenFilter(
val cookies = httpServeletRequest.cookies
var hasToken : Boolean = false
var accesToken : String = ""
if(cookies==null) throw Exception()

for(cookie in cookies){
//Cookie들 중 AccessToken을 갖고 있는지
if(cookie.name.equals(ACCESSTOKEN_COOKIE)){
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.tinuproject.tinu.security.oauth2.dto

class KakaoUserInfo(
private var attributes: Map<String, Any>
) :OAuth2UserInfoDto {
override fun getProviderId(): String {
return attributes["id"].toString()
}

override fun getProvider(): String {
return "kakao"
}

override fun getName() :String{

return (attributes["properties"] as Map<*, *>)["nickname"].toString()

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.tinuproject.tinu.security.oauth2.dto

class NaverUserInfo(
private var attributes: Map<String, Any>
):OAuth2UserInfoDto {
override fun getProviderId(): String {
return attributes["id"].toString()
}

override fun getProvider(): String {
return "naver"
}

override fun getName() : String {
return attributes["name"].toString()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.tinuproject.tinu.security.oauth2.dto

interface OAuth2UserInfoDto {
fun getProviderId() : String

fun getProvider() : String

fun getName() : String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.tinuproject.tinu.security.oauth2.dto

import java.util.*

class UserInfoDto (
var uuid : UUID,

var name : String,

var providerId : String,

var provider : String
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.tinuproject.tinu.security.oauth2.handler

import jakarta.servlet.ServletException
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.security.core.AuthenticationException
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler
import org.springframework.stereotype.Component
import java.io.IOException

@Component
class OAuthLoginFailureHandler(): SimpleUrlAuthenticationFailureHandler() {
var log : Logger = LoggerFactory.getLogger(this::class.java)

@Throws(IOException::class, ServletException::class)
override fun onAuthenticationFailure(
request: HttpServletRequest?,
response: HttpServletResponse?,
exception: AuthenticationException
) {
log.error("LOGIN FAILED : {}", exception.message)
super.onAuthenticationFailure(request, response, exception)
}
}
Loading

0 comments on commit 4e7e1e1

Please sign in to comment.