Skip to content

Commit

Permalink
Merge branch 'weekly_11' into feat/58/get-my-orders
Browse files Browse the repository at this point in the history
  • Loading branch information
ajy9851 authored Nov 13, 2024
2 parents 3f5cc53 + 65d8923 commit 015544d
Show file tree
Hide file tree
Showing 19 changed files with 207 additions and 54 deletions.
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation "io.jsonwebtoken:jjwt-api:${jjwt_version}"
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${swagger_version}"
implementation 'org.mapstruct:mapstruct:1.6.2'
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
implementation 'ch.hsr:geohash:1.4.0'
implementation 'net.nurigo:sdk:4.3.0'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.6.2'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
// testImplementation 'org.springframework.security:spring-security-test'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.ordertogether.team14_be.auth.application.service;

import com.ordertogether.team14_be.auth.JwtUtil;
import com.ordertogether.team14_be.auth.persistence.JwtUtil;
import com.ordertogether.team14_be.auth.persistence.exception.AlreadyExistMember;
import com.ordertogether.team14_be.member.application.service.MemberService;
import com.ordertogether.team14_be.member.persistence.entity.Member;
import java.util.Optional;
import org.springframework.stereotype.Service;

@Service
Expand All @@ -15,15 +17,14 @@ public AuthService(MemberService memberService, JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}

public String register(String email, String deliveryName, String phoneNumber) {
Member member = new Member(email, deliveryName, phoneNumber);
memberService.registerMember(member);
Long memberId = memberService.getMemberId(email);
String serviceToken = jwtUtil.generateToken(memberId);
return serviceToken;
}

public String getServiceToken(String email) {
return jwtUtil.generateToken(memberService.getMemberId(email));
}

public void validMember(String email, String platform) {
Optional<Member> isAlreadyMember = memberService.findMemberByEmail(email);
if (isAlreadyMember.isPresent() && isAlreadyMember.get().getPlatform().equals(platform)) {
throw new AlreadyExistMember();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
package com.ordertogether.team14_be.auth.application.service;

import com.ordertogether.team14_be.auth.application.dto.KakaoUserInfo;
import com.ordertogether.team14_be.auth.persistence.JwtUtil;
import com.ordertogether.team14_be.auth.presentation.KakaoClient;
import com.ordertogether.team14_be.member.application.service.MemberService;
import com.ordertogether.team14_be.member.persistence.entity.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Service
public class KakaoAuthService {
private final KakaoClient kakaoClient;
private final MemberService memberService;
private final JwtUtil jwtUtil;
private static final String LOGIN_PLATFORM = "KAKAO";
private final AuthService authService;

public String getKakaoUserEmail(String authorizationCode) {
String kakaoToken = kakaoClient.getAccessToken(authorizationCode);
KakaoUserInfo kakaoUserInfo = kakaoClient.getUserInfo((kakaoToken));
String userKakaoEmail = kakaoUserInfo.kakaoAccount().email();
return userKakaoEmail;
}

public String register(String email, String deliveryName, String phoneNumber) {
Member member = new Member(email, 0, phoneNumber, deliveryName, LOGIN_PLATFORM);
authService.validMember(email, LOGIN_PLATFORM);
memberService.registerMember(member);
Long memberId = memberService.getMemberId(email);
String serviceToken = jwtUtil.generateToken(memberId);
return serviceToken;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.ordertogether.team14_be.auth.persistence;

import com.ordertogether.team14_be.member.application.exception.NotFoundMember;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@RequiredArgsConstructor
@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {
private final JwtUtil jwtUtil;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
return true;
}

String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
String token = authorization.replaceAll("Bearer ", "");

if (token != null && token.length() > 10) {
log.debug("토큰 상태:: " + token);

if (jwtUtil.vaildToken(token)) {
String memberIdString = jwtUtil.decodeJwt(token).getSubject();
Long memberId = Long.parseLong(memberIdString);

request.setAttribute("memberId", memberId);
return true;
}
} else {
throw new NotFoundMember();
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.ordertogether.team14_be.auth;
package com.ordertogether.team14_be.auth.persistence;

import com.ordertogether.team14_be.auth.persistence.exception.InvalidToken;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -38,4 +40,17 @@ public String generateToken(Long data) {
public Claims decodeJwt(String token) {
return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
}

public boolean vaildToken(String token) throws InvalidToken {
try {
Claims claims =
Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token) // 토큰 파싱
.getBody();
return true; // 유효하다면 true 반환
} catch (MalformedJwtException e) {
throw new InvalidToken();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ordertogether.team14_be.auth.persistence.exception;

public class AlreadyExistMember extends RuntimeException {
public AlreadyExistMember() {
super("이미 회원이 존재합니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ordertogether.team14_be.auth.persistence.exception;

public class InvalidToken extends IllegalAccessException {
public InvalidToken() {
super("토큰이 유효하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,23 @@
import com.ordertogether.team14_be.member.application.dto.MemberInfoRequest;
import com.ordertogether.team14_be.member.application.service.MemberService;
import com.ordertogether.team14_be.member.persistence.entity.Member;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Controller
@RequestMapping("/api/v1/auth")
public class AuthController {

Expand All @@ -44,8 +43,12 @@ public AuthController(
}

@GetMapping("/login")
public ResponseEntity<ApiResponse<String>> getToken(@RequestHeader String authorizationCode) {
public ResponseEntity<ApiResponse<String>> getToken(
@RequestHeader("Authorization") String authorizationHeader,
HttpServletResponse httpServletResponse) {
String authorizationCode = authorizationHeader.replace("Bearer ", "");
String userKakaoEmail = kakaoAuthService.getKakaoUserEmail(authorizationCode);
System.out.println("이메일:" + userKakaoEmail);
Optional<Member> existMember = memberService.findMemberByEmail(userKakaoEmail);
if (existMember.isPresent()) {
String serviceToken = authService.getServiceToken(userKakaoEmail);
Expand All @@ -65,20 +68,22 @@ public ResponseEntity<ApiResponse<String>> getToken(@RequestHeader String author
.headers(headers)
.body(ApiResponse.with(HttpStatus.OK, "로그인 성공", serviceToken));
} else {
return ResponseEntity.status(HttpStatus.FOUND)
.location(
URI.create(redirectPage + URLEncoder.encode(userKakaoEmail, StandardCharsets.UTF_8)))
.build();
String redirectUrl = redirectPage + userKakaoEmail;
try {
httpServletResponse.sendRedirect(redirectUrl);
} catch (IOException e) {
System.out.println(e.getMessage());
}
return ResponseEntity.ok().body(ApiResponse.with(HttpStatus.FOUND, "리다이렉트", redirectUrl));
}
}

@PostMapping("/signup")
public ResponseEntity<ApiResponse<String>> signUpMember(
@RequestParam String email, @RequestBody MemberInfoRequest memberInfoRequest) {
String serviceToken =
authService.register(
kakaoAuthService.register(
email, memberInfoRequest.deliveryName(), memberInfoRequest.phoneNumber());

ResponseCookie cookie =
ResponseCookie.from("serviceToken", serviceToken)
.httpOnly(true)
Expand All @@ -94,4 +99,24 @@ public ResponseEntity<ApiResponse<String>> signUpMember(
.headers(headers)
.body(ApiResponse.with(HttpStatus.OK, "회원가입 성공", serviceToken));
}

@PostMapping("/logout")
public ResponseEntity<ApiResponse<String>> logout(HttpServletResponse response) {

ResponseCookie deleteCookie =
ResponseCookie.from("serviceToken", "")
.maxAge(0)
.httpOnly(true)
.secure(true)
.path("/")
.sameSite("Strict")
.build();

HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.SET_COOKIE, deleteCookie.toString());

return ResponseEntity.ok()
.headers(headers)
.body(ApiResponse.with(HttpStatus.OK, "로그아웃 성공", ""));
}
}
20 changes: 16 additions & 4 deletions src/main/java/com/ordertogether/team14_be/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
package com.ordertogether.team14_be.config;

import com.ordertogether.team14_be.auth.persistence.JwtInterceptor;
import com.ordertogether.team14_be.member.application.LoginMemberArgumentResolver;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@RequiredArgsConstructor
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
private final LoginMemberArgumentResolver loginMemberArgumentResolver;

public WebConfig(LoginMemberArgumentResolver loginMemberArgumentResolver) {
this.loginMemberArgumentResolver = loginMemberArgumentResolver;
}
private final JwtInterceptor jwtInterceptor;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(loginMemberArgumentResolver);
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry
.addInterceptor(jwtInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(
"/signup", "/api/v1/auth/signup", "/api/v1/auth/login", "/api/v1/spot/**");
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.ordertogether.team14_be.member.application;

import com.ordertogether.team14_be.auth.JwtUtil;
import com.ordertogether.team14_be.auth.persistence.JwtUtil;
import com.ordertogether.team14_be.member.application.service.MemberService;
import com.ordertogether.team14_be.member.persistence.MemberRepository;
import com.ordertogether.team14_be.member.presentation.LoginMember;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import java.util.NoSuchElementException;

public class NotFoundMember extends NoSuchElementException {

public NotFoundMember() {
super("회원정보가 존재하지 않습니다");
super("회원정보가 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.ordertogether.team14_be.member.application.service;

import com.ordertogether.team14_be.auth.JwtUtil;
import com.ordertogether.team14_be.auth.persistence.JwtUtil;
import com.ordertogether.team14_be.member.application.dto.MemberInfoResponse;
import com.ordertogether.team14_be.member.application.exception.NotFoundMember;
import com.ordertogether.team14_be.member.persistence.MemberRepository;
import com.ordertogether.team14_be.member.persistence.entity.Member;
import java.util.NoSuchElementException;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -23,7 +22,7 @@ public Long getMemberId(String email) {
return memberRepository
.findByEmail(email)
.map(Member::getId)
.orElseThrow(() -> new NoSuchElementException("Member with email " + email + " not found"));
.orElseThrow(() -> new NotFoundMember());
}

@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

@Entity
public class Member {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down Expand Up @@ -48,12 +47,6 @@ public Member(String email, int point, String phoneNumber, String deliveryName,
this.platform = platform;
}

public Member(String email, String phoneNumber, String deliveryName) {
this.email = email;
this.phoneNumber = phoneNumber;
this.deliveryName = deliveryName;
}

public Long getId() {
return id;
}
Expand Down
Loading

0 comments on commit 015544d

Please sign in to comment.