Skip to content

Commit e3c79e2

Browse files
committed
feat: 로그인 리스폰스 수정
1 parent f610774 commit e3c79e2

3 files changed

Lines changed: 63 additions & 65 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.waitit.capstone.domain.auth.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
7+
@Getter
8+
@Builder
9+
@JsonInclude(JsonInclude.Include.NON_NULL) // null인 필드는 JSON 응답에서 제외
10+
public class LoginResponseDto {
11+
private String message;
12+
private String phoneNumber;
13+
private String name;
14+
private String role;
15+
private String refresh; // 모바일 클라이언트용
16+
}

src/main/java/com/waitit/capstone/global/config/SecurityConfig.java

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.waitit.capstone.global.config;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper; // ObjectMapper 임포트 추가
34
import com.waitit.capstone.domain.auth.service.CustomOAuth2UserService;
45
import com.waitit.capstone.domain.auth.service.RefreshTokenService;
56
import com.waitit.capstone.global.security.jwt.CustomLogoutFilter;
@@ -33,25 +34,23 @@
3334
@AllArgsConstructor
3435
public class SecurityConfig {
3536

36-
//AuthenticationManager가 인자로 받을 AuthenticationConfiguraion 객체 생성자 주입
3737
private final AuthenticationConfiguration authenticationConfiguration;
3838
private final JWTUtil jwtUtil;
3939
private final RefreshTokenService refreshTokenService;
4040
private final RefreshTokenResolver refreshTokenResolver;
4141
private final CustomOAuth2UserService customOAuth2UserService;
42+
private final ObjectMapper objectMapper; // ObjectMapper 주입 추가
4243

43-
44-
//AuthenticationManager Bean 등록
4544
@Bean
4645
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
4746
return configuration.getAuthenticationManager();
4847
}
49-
@Bean //비밀번호 암호화 객체 생성
48+
@Bean
5049
public BCryptPasswordEncoder bCryptPasswordEncoder(){
5150
return new BCryptPasswordEncoder();
5251
}
5352

54-
@Bean //cors 설정 빈
53+
@Bean
5554
public CorsConfigurationSource corsConfigurationSource() {
5655
CorsConfiguration config = new CorsConfiguration();
5756
config.setAllowedOriginPatterns(List.of("*"));
@@ -68,41 +67,25 @@ public CorsConfigurationSource corsConfigurationSource() {
6867

6968
@Bean
7069
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
71-
//cors 설정
7270
http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
73-
//csrf disable
7471
http.csrf(AbstractHttpConfigurer::disable);
75-
76-
//form 로그인 방식 disable
7772
http.formLogin(AbstractHttpConfigurer::disable);
78-
79-
//http basic 인증방식 disable
8073
http.httpBasic(AbstractHttpConfigurer::disable);
8174

82-
//oauth2
8375
http
8476
.oauth2Login((oauth2)->oauth2
8577
.userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig
8678
.userService(customOAuth2UserService)));
8779

88-
//경로별 인가작업 -> 일단 작업을 위해 모두 허용
89-
/*.authorizeHttpRequests((auth) -> auth
90-
.requestMatchers("/login", "/", "/join").permitAll()
91-
.requestMatchers("/admin").hasRole("ADMIN")
92-
.anyRequest().authenticated());
93-
*/
9480
http.authorizeHttpRequests(auth->auth.anyRequest().permitAll());
9581

96-
//JWTFilter 등록
9782
http.addFilterAfter(new JWTFilter(jwtUtil), LoginFilter.class);
9883

99-
//필터 추가 LoginFilter()는 인자를 받음 (AuthenticationManager() 메소드에 authenticationConfiguration 객체를 넣어야 함)
100-
http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration),jwtUtil,refreshTokenService), UsernamePasswordAuthenticationFilter.class);
84+
// LoginFilter 생성자에 objectMapper 추가
85+
http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil, refreshTokenService, objectMapper), UsernamePasswordAuthenticationFilter.class);
10186

102-
//로그아웃 필터 추가
10387
http.addFilterBefore(new CustomLogoutFilter(jwtUtil,refreshTokenService,refreshTokenResolver), LogoutFilter.class);
10488

105-
//세션을 아예 안만들도록 설정 -> 로그인해도 서버에 세션객체 저장X
10689
http.sessionManagement((session)->session
10790
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
10891
return http.build();

src/main/java/com/waitit/capstone/global/security/jwt/LoginFilter.java

Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
package com.waitit.capstone.global.security.jwt;
22

3-
import com.waitit.capstone.domain.auth.dto.LoginRequest;
43
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.waitit.capstone.domain.auth.dto.LoginRequest;
5+
import com.waitit.capstone.domain.auth.dto.LoginResponseDto;
56
import com.waitit.capstone.domain.auth.service.RefreshTokenService;
67
import jakarta.servlet.FilterChain;
78
import jakarta.servlet.ServletInputStream;
89
import jakarta.servlet.http.Cookie;
910
import jakarta.servlet.http.HttpServletRequest;
1011
import jakarta.servlet.http.HttpServletResponse;
11-
import java.io.IOException;
12-
import java.nio.charset.StandardCharsets;
13-
import lombok.AllArgsConstructor;
1412
import lombok.extern.slf4j.Slf4j;
1513
import org.springframework.http.HttpStatus;
1614
import org.springframework.security.authentication.AuthenticationManager;
@@ -20,22 +18,29 @@
2018
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
2119
import org.springframework.util.StreamUtils;
2220

21+
import java.io.IOException;
22+
import java.nio.charset.StandardCharsets;
23+
2324
@Slf4j
24-
@AllArgsConstructor
2525
public class LoginFilter extends UsernamePasswordAuthenticationFilter {
2626

2727
private final AuthenticationManager authenticationManager;
2828
private final JWTUtil jwtUtil;
2929
private final RefreshTokenService refreshTokenService;
30+
private final ObjectMapper objectMapper;
31+
32+
public LoginFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, ObjectMapper objectMapper) {
33+
this.authenticationManager = authenticationManager;
34+
this.jwtUtil = jwtUtil;
35+
this.refreshTokenService = refreshTokenService;
36+
this.objectMapper = objectMapper;
37+
}
3038

3139
@Override
3240
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
3341
throws AuthenticationException {
34-
// 클라이언트 요청에서 username, password 추출
3542
LoginRequest loginRequest = new LoginRequest();
36-
3743
try {
38-
ObjectMapper objectMapper = new ObjectMapper();
3944
ServletInputStream inputStream = request.getInputStream();
4045
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
4146
loginRequest = objectMapper.readValue(messageBody, LoginRequest.class);
@@ -47,63 +52,57 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ
4752

4853
String username = loginRequest.getUsername();
4954
String password = loginRequest.getPassword();
50-
// 인증을 위해 토큰으로 변환
51-
UsernamePasswordAuthenticationToken token =
52-
new UsernamePasswordAuthenticationToken(username, password, null);
53-
55+
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password, null);
5456
return authenticationManager.authenticate(token);
5557
}
5658

57-
// 로그인 성공 시 실행하는 메소드 (여기서 JWT를 발급하면 됨)
5859
@Override
5960
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
6061
FilterChain chain, Authentication authentication) throws IOException {
61-
String username = authentication.getName();
62+
String phoneNumber = authentication.getName();
6263
String role = authentication.getAuthorities().iterator().next().getAuthority();
63-
String name = refreshTokenService.findMember(username);
64+
String name = refreshTokenService.findMember(phoneNumber);
6465
long accessExpireMs = 600000L;
6566
long refreshExpireMs = 86400000L;
6667

67-
String access = jwtUtil.createJwt("access", username, role, accessExpireMs);
68-
String refresh = jwtUtil.createJwt("refresh", username, role, refreshExpireMs);
69-
70-
// Refresh 토큰 저장
71-
refreshTokenService.save(username, refresh, refreshExpireMs);
68+
String access = jwtUtil.createJwt("access", phoneNumber, role, accessExpireMs);
69+
String refresh = jwtUtil.createJwt("refresh", phoneNumber, role, refreshExpireMs);
7270

73-
// 클라이언트 타입 구분
74-
String clientType = request.getHeader("X-Client-Type");
71+
refreshTokenService.save(phoneNumber, refresh, refreshExpireMs);
7572

76-
// 공통: access token은 헤더에 설정 (REST 표준)
7773
response.setHeader("Authorization", "Bearer " + access);
74+
response.setContentType("application/json");
75+
response.setCharacterEncoding("UTF-8");
76+
77+
String clientType = request.getHeader("X-Client-Type");
78+
LoginResponseDto loginResponse;
7879

7980
if ("mobile".equalsIgnoreCase(clientType)) {
80-
// 모바일: JSON 응답
81-
String jsonResponse = "{\"message\": \"로그인에 성공했습니다.\", " +
82-
"\"username\": \"" + username + "\", " +
83-
"\"name\": \"" + name + "\", " +
84-
"\"role\": \"" + role + "\", " +
85-
"\"refresh\": \"" + refresh + "\"}";
86-
response.setContentType("application/json");
87-
response.setCharacterEncoding("UTF-8");
88-
response.getWriter().write(jsonResponse);
81+
loginResponse = LoginResponseDto.builder()
82+
.message("로그인에 성공했습니다.")
83+
.phoneNumber(phoneNumber)
84+
.name(name)
85+
.role(role)
86+
.refresh(refresh)
87+
.build();
8988
} else {
90-
// 웹: HttpOnly 쿠키로 refresh 토큰 전달
9189
Cookie refreshCookie = jwtUtil.createCookie("refresh", refresh);
9290
refreshCookie.setSecure(true);
9391
refreshCookie.setPath("/");
9492
response.addCookie(refreshCookie);
95-
String jsonResponse = "{\"message\": \"로그인에 성공했습니다.\", " +
96-
"\"username\": \"" + username + "\", " +
97-
"\"name\": \"" + name + "\", " +
98-
"\"role\": \"" + role + "\"}";
99-
response.setContentType("application/json");
100-
response.setCharacterEncoding("UTF-8");
101-
response.getWriter().write(jsonResponse);
102-
response.setStatus(HttpStatus.OK.value());
93+
94+
loginResponse = LoginResponseDto.builder()
95+
.message("로그인에 성공했습니다.")
96+
.phoneNumber(phoneNumber)
97+
.name(name)
98+
.role(role)
99+
.build();
103100
}
101+
102+
response.getWriter().write(objectMapper.writeValueAsString(loginResponse));
103+
response.setStatus(HttpStatus.OK.value());
104104
}
105105

106-
// 로그인 실패 시 실행하는 메소드
107106
@Override
108107
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
109108
AuthenticationException failed) throws IOException {

0 commit comments

Comments
 (0)