Compare commits

...

10 Commits

Author SHA1 Message Date
root
030d3c4ceb interceptor 2025-09-15 13:01:59 +09:00
root
ec2201278f 로그인 성공 2025-09-09 12:59:32 +09:00
root
840ce1d4ce 수정중 2025-09-04 13:01:13 +09:00
root
5762f80bcd login success 2025-08-27 13:01:00 +09:00
root
5bd68b2fcb webclient 2025-08-12 18:05:28 +09:00
root
603b992dd1 webclient 2025-08-04 12:57:54 +09:00
root
79b98f4321 login 2025-07-30 12:59:47 +09:00
root
8dc0bac98c 로그인 성공 데이터 받아야함 2025-07-25 16:25:41 +09:00
root
8132000b92 프론트에서 보내도록 수정해야함 2025-07-22 18:33:09 +09:00
hanwha
05406e7b7a CORS setting 2025-07-21 11:52:46 +09:00
13 changed files with 236 additions and 26 deletions

View File

@@ -39,6 +39,9 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.5' implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
//webclient
implementation 'org.springframework.boot:spring-boot-starter-webflux'
} }
tasks.named('test') { tasks.named('test') {

View File

@@ -0,0 +1,33 @@
package site.ocr.prd;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors(cors -> {
CorsConfigurationSource configurationSource = request -> { //되게 스크립트같다...
CorsConfiguration configuration = new CorsConfiguration();
//여러개 추가할거면 addAllowd~가 아니라 setAllowedOrigins 사용하기
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
configuration.setAllowedMethods(List.of("GET","POST", "PUT","DELETE","OPTION"));
configuration.setAllowedHeaders(List.of("*"));
return configuration;
};
cors.configurationSource(configurationSource);
})
.csrf(AbstractHttpConfigurer::disable); //대체 언제 이런 문법이 생겼냐;
return http.build();
}
}

View File

@@ -0,0 +1,37 @@
package site.ocr.prd;
import java.util.Enumeration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@Component
public class SessionLoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//현재 세션이 있으면 가져오기, 없으면 null
HttpSession sessoin = request.getSession(false);
if (sessoin != null) {
StringBuilder sb = new StringBuilder("[SESSION DEBUG] :: ");
//세션ID(누구 세션인지)
sb.append("ID=").append(sessoin.getId()).append("\\n");
//세션값
Enumeration<String> attrvName = sessoin.getAttributeNames();
while (attrvName.hasMoreElements()) {
String name = attrvName.nextElement();
String value = (String) sessoin.getAttribute(name);
sb.append("NAME=").append(name).append(", ").append("VALUE=").append(value).append("\\n");
}
System.out.println(sb.toString());
} else {
System.out.println("[SESSION DEBUG] :: No session found.");
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
}

View File

@@ -0,0 +1,16 @@
package site.ocr.prd;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
@Bean
public WebClient webClient() {
return WebClient.builder()
.build();
}
}

View File

@@ -1,16 +0,0 @@
package site.ocr.prd;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true);
}
}

View File

@@ -0,0 +1,19 @@
package site.ocr.prd;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Autowired
private SessionLoggingInterceptor sessionLoggingInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
WebMvcConfigurer.super.addInterceptors(registry);
registry.addInterceptor(sessionLoggingInterceptor).addPathPatterns("/**");
}
}

View File

@@ -1,18 +1,47 @@
package site.ocr.prd.contorllers; package site.ocr.prd.contorllers;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import jakarta.servlet.http.HttpServletRequest;
import site.ocr.prd.dto.LoginRequestDto;
import site.ocr.prd.dto.LoginResponseDto;
import site.ocr.prd.services.LoginService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@RestController @RestController
public class LoginController { public class LoginController {
//service 선언
private LoginService loginService = new LoginService(WebClient.builder());
@PostMapping("login/oauth-kakao") @GetMapping("login/oauth-kakao-authorize") //kakao에서 get으로 요청 보냄
public String postMethodName(@RequestBody String entity) { public void kakaoLoginRequestDto(HttpServletRequest request) {
String accessToken = request.getParameter("code");
System.out.println(accessToken);
LoginRequestDto requestDTO = new LoginRequestDto();
requestDTO.setGrant_type("authorization_code");
requestDTO.setClient_id("a1d6afef2d4508a10a498b7069f67496");
requestDTO.setRedirect_uri("http://localhost:9001/login/oauth-kakao-authorize");
requestDTO.setCode(accessToken);
LoginResponseDto result = loginService.getToken(requestDTO);
System.out.println(result.toString());
}
@PostMapping("login/oauth-kakao-token")
public String kakaoLoginResponseDto(@RequestBody LoginResponseDto response) {
//TODO: process POST request //TODO: process POST request
System.out.println(entity); System.out.println("response :: ");
return entity; System.out.println(response.getAccess_token());
return response.getAccess_token();
} }
} }

View File

@@ -0,0 +1,21 @@
package site.ocr.prd.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ToString
@Getter
@Setter
public class LoginRequestDto {
@JsonProperty("grant_type")
String grant_type; //authorization_code
@JsonProperty("client_id")
String client_id; //앱 REST API 키
@JsonProperty("redirect_uri")
String redirect_uri; //인가코드가 리다이렉트된 uri
String code; //인가코드 요청으로 얻은 인가코드
}

View File

@@ -0,0 +1,27 @@
package site.ocr.prd.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ToString
@Getter
@Setter
public class LoginResponseDto {
@JsonProperty("token_type")
String token_type; //토큰타입, bearer 고정
@JsonProperty("access_token")
String access_token; //사용자 엑세스 토큰 값
@JsonProperty("id_token")
String id_token; //ID 토큰값, openID connect가 활성화된 경우만 발급
@JsonProperty("expires_in")
Integer expires_in; //엑세스토큰과 id토큰의 만료시간(초))
@JsonProperty("refresh_token")
String refresh_token; //사용자 리프레시 토큰 값
@JsonProperty("refresh_token_expires_in")
Integer refresh_token_expires_in; //리프레시 토큰 만료 시간(초)
String scope; //인증된 사용자의 정보조회 범위, 여러개일 경우 공백으로 구분
}

View File

@@ -0,0 +1,39 @@
package site.ocr.prd.services;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.http.HttpHeaders;
import site.ocr.prd.dto.LoginRequestDto;
import site.ocr.prd.dto.LoginResponseDto;
@Service
public class LoginService {
private final WebClient webClient;
public LoginService(WebClient.Builder builder) {
this.webClient = builder.build();
}
public LoginResponseDto getToken(LoginRequestDto request) {
LoginResponseDto result = webClient.post()
.uri("https://kauth.kakao.com/oauth/token")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.body(BodyInserters.fromFormData("grant_type", "authorization_code")
.with("client_id", "a1d6afef2d4508a10a498b7069f67496")
.with("redirect_uri", "http://localhost:9001/login/oauth-kakao-authorize")
.with("code", request.getCode()))
.retrieve()
.bodyToMono(LoginResponseDto.class)
//.bodyToMono(String.class)
.block();
//System.out.println("요청 ::: " + request.toString());
//System.out.println("성공여부 ::: " + "result");
return result;
}
}

View File

@@ -1,5 +1,8 @@
spring: spring:
profiles: DEV config:
activate:
on-profile:
- DEV
server: server:
port: 9001 port: 9001
logging: logging:

View File

@@ -1,6 +1,5 @@
#로컬 실행시 기본 프로필 #로컬 실행시 기본 프로필
spring: spring:
config: profiles:
activate: active:
on-profile: - DEV
- DEV