Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import jakarta.servlet.http.Cookie;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
Expand Down Expand Up @@ -62,7 +63,19 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
// boolean isNewMember = member.getCreatedAt().equals(member.getUpdatedAt());

// Access Token, Refresh Token 발급
String newAccessToken = authCommandService.processLoginSuccess(member, response);
String newRefreshToken = authCommandService.processLoginKakaoSuccess(member, response);

// 쿠키에 저장
// Refresh Token을 HTTP-Only, Secure 쿠키로 설정
Cookie refreshTokenCookie = new Cookie("refresh_token", newRefreshToken);
refreshTokenCookie.setHttpOnly(true); // JavaScript 접근 차단
refreshTokenCookie.setSecure(true); // HTTPS에서만 전송 (로컬 개발 시 false 가능)
refreshTokenCookie.setPath("/"); // 모든 경로에서 사용 가능
refreshTokenCookie.setMaxAge(7 * 24 * 60 * 60); // 7일 유효기간 설정

// SameSite 설정을 위한 헤더 추가
response.setHeader("Set-Cookie", "refresh_token=" + newRefreshToken +
"; Path=/; HttpOnly; Secure; SameSite=None; Max-Age=" + (7 * 24 * 60 * 60));

String tempUrl = (!member.isRegistrationCompleted()) ? FRONT_SIGNUP_URL : FRONT_HOME_URL;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@ protected boolean shouldNotFilter(HttpServletRequest request) throws ServletExce
uri = uri.substring(contextPath.length());
}
log.info("JwtAuthenticationFilter - Request URI after context removal: {}", uri);
boolean skip = uri.startsWith("/auth/")
&& !uri.startsWith("/auth/signup/complete")
&& !uri.startsWith("/auth/logout")||
boolean skip = uri.startsWith("/auth/reissue") ||
uri.startsWith("/oauth2/") ||
uri.startsWith("/email/") ||
uri.startsWith("/swagger-ui/") ||
uri.startsWith("/v3/api-docs/");

skip = (!uri.startsWith("/auth/signup/complete")
&& !uri.startsWith("/auth/logout")) && skip;


log.info("JwtAuthenticationFilter - shouldNotFilter returns: {}", skip);
return skip;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public interface AuthCommandService {
void logout(String refreshToken);

String processLoginSuccess(Member member, HttpServletResponse response);

String processLoginKakaoSuccess(Member member, HttpServletResponse response);
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,17 @@ public String processLoginSuccess(Member member, HttpServletResponse response) {

return newAccessToken;
}

// 카카오 전용, 리프레시 토큰 발급
@Override
public String processLoginKakaoSuccess(Member member, HttpServletResponse response) {
// Access Token, Refresh Token 발급
String newAccessToken = jwtProvider.createAccessToken(member.getId().toString());
String newRefreshToken = jwtProvider.createRefreshToken(member.getId().toString());

// Refresh Token 저장
saveRefreshToken(member, newRefreshToken);

return newRefreshToken;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

@Repository
public interface MemberBodyTypeRepository extends JpaRepository<MemberBodyType, Long> {
Optional<MemberBodyType> findTopByMemberOrderByCreatedAt(Member member);
Long countAllByMember(Member member);
Optional<MemberBodyType> findTopByMemberOrderByCreatedAtDesc(Member member);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class BodyTypeService {
* @return 마지막 체형 분석이 존재하지 않을 경우 empty Optional을 반환함.
*/
public Optional<BodyType> findLastBodyType(Member member){
Optional<MemberBodyType> optionalMemberBodyType = memberBodyTypeRepository.findTopByMemberOrderByCreatedAt(member);
Optional<MemberBodyType> optionalMemberBodyType = memberBodyTypeRepository.findTopByMemberOrderByCreatedAtDesc(member);
return optionalMemberBodyType.map(MemberBodyType::getBodyType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ public class Member extends BaseEntity {
@Enumerated(EnumType.STRING)
private LoginType loginType;

@Builder.Default
private boolean isRegistrationCompleted = false; // 회원가입 완료 여부
@Column(columnDefinition = "boolean default false")
private boolean isRegistrationCompleted; // 회원가입 완료 여부

public void completeRegistration(String nickname, LocalDate birthDate, Gender gender, Integer height
, String profileImageUrl) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.mody.domain.member.service;

import jakarta.persistence.EntityManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -27,11 +29,12 @@ public class MemberCommandServiceImpl implements MemberCommandService {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
private final AuthCommandService authCommandService;
private final MemberQueryService memberQueryService;

@Override
public void completeRegistration(Member member, MemberRegistrationRequest request) {

member.completeRegistration(
Member unregisteredMember = memberQueryService.findMemberById(member.getId()); // 영속성 컨텍스트가 관리하도록
unregisteredMember.completeRegistration(
request.getNickname(),
request.getBirthDate(),
request.getGender(),
Expand Down