Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue63/refresh token logic feat #65

Merged
Merged
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
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