Skip to content

Commit

Permalink
Merge branch 'feat/LS-6' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondanythings committed Jul 10, 2024
2 parents d343ca8 + f14ad8d commit 332a261
Show file tree
Hide file tree
Showing 54 changed files with 1,030 additions and 110 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# auth
layer-api/src/main/resources/application-auth.properties
layer-api/src/main/resources/application.*
layer-external/src/main/resources/application-oauth.properties
layer-external/src/main/resources/application-oauth.yaml
layer-external/src/main/resources/application.yaml
layer-api/src/main/resources/application.yaml
layer-external/src/main/resources/application.yml


HELP.md
.gradle
build/
Expand Down
16 changes: 13 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ subprojects {
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'

implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'

}

test {
Expand All @@ -60,8 +63,7 @@ project(":layer-api") {
implementation project(path: ':layer-domain')
implementation project(path: ':layer-external')

implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'

implementation 'org.springframework.boot:spring-boot-starter-actuator'

//== jwt ==//
Expand All @@ -74,8 +76,15 @@ project(":layer-api") {

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

testImplementation 'org.springframework.boot:spring-boot-starter-test'

// jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

//Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

runtimeOnly 'com.mysql:mysql-connector-j'
}

jar.enabled = false
Expand All @@ -88,6 +97,7 @@ project(":layer-common") {

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
// implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}

}
Expand Down
Empty file removed layer-api/build.gradle
Empty file.

This file was deleted.

28 changes: 0 additions & 28 deletions layer-api/src/main/java/org/layer/auth/api/AuthController.java

This file was deleted.

This file was deleted.

16 changes: 0 additions & 16 deletions layer-api/src/main/java/org/layer/auth/jwt/JwtToken.java

This file was deleted.

11 changes: 11 additions & 0 deletions layer-api/src/main/java/org/layer/common/annotation/MemberId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.layer.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface MemberId {
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.layer.common.exception;

import lombok.extern.slf4j.Slf4j;
import org.layer.common.exception.BaseCustomException;
import org.layer.common.exception.ExceptionType;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand Down
4 changes: 4 additions & 0 deletions layer-api/src/main/java/org/layer/config/AuthValueConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ public class AuthValueConfig {
@Value("${jwt.secret}")
private String JWT_SECRET;


public static final Long ACCESS_TOKEN_EXPIRATION_TIME = 1000 * 60 * 30L; // 30분
public static final Long REFRESH_TOKEN_EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 14L; // 2주
public static final String AUTHORIZATION = "Authorization";
public static final String KAKAO_URI = "https://kapi.kakao.com/v2/user/me";



@PostConstruct
Expand Down
12 changes: 7 additions & 5 deletions layer-api/src/main/java/org/layer/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


import lombok.RequiredArgsConstructor;
import org.layer.auth.jwt.JwtAuthenticationFilter;
import org.layer.domain.jwt.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
Expand Down Expand Up @@ -35,7 +35,12 @@ private void setHttp(HttpSecurity http) throws Exception {
session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
).authorizeHttpRequests(authorizeRequest ->
authorizeRequest
.requestMatchers(new AntPathRequestMatcher("/create-token")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/auth/sign-in")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/auth/reissue-token")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/auth/sign-up")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/auth/oauth2/google")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/test")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/api/auth/oauth2/kakao")).permitAll()
.anyRequest().authenticated()
);
}
Expand All @@ -47,7 +52,4 @@ private void permitSwaggerUri(HttpSecurity http) throws Exception {
.requestMatchers(new AntPathRequestMatcher("/swagger-ui/**")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/docs/**")).permitAll());
}



}
60 changes: 60 additions & 0 deletions layer-api/src/main/java/org/layer/config/SwaggerConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.layer.config;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.layer.common.annotation.MemberId;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;

import java.util.Arrays;

@Configuration
public class SwaggerConfig {

SecurityScheme apiAuth = new SecurityScheme()
.type(SecurityScheme.Type.APIKEY)
.in(SecurityScheme.In.HEADER)
.name("authorization-token");

SecurityRequirement addSecurityItem = new SecurityRequirement()
.addList("authorization-token");

@Bean
public OpenAPI openAPI(){
var info = new Info();
info.title("Layer API");
info.description("Layer API 문서에요.");
info.contact(
new Contact()
.email("[email protected]")
.name("떡잎마을방범대")
);
info.license(new License().name("MIT"));
return new OpenAPI()
.components(new Components()
.addSecuritySchemes("authorization-token", apiAuth)
)
.addSecurityItem(addSecurityItem)
.info(info);
}

@Bean
public OperationCustomizer customizeOperation() {
return (operation, handlerMethod) -> {
HandlerMethod method = (HandlerMethod) handlerMethod;
method.getMethodParameters();
method.getMethodParameters();
if (Arrays.stream(method.getMethodParameters()).anyMatch(param -> param.hasParameterAnnotation(MemberId.class))) {
operation.getParameters().removeIf(param -> "memberId".equals(param.getName()));
}
return operation;
};
}
}
41 changes: 41 additions & 0 deletions layer-api/src/main/java/org/layer/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.layer.config;

import lombok.RequiredArgsConstructor;
import org.layer.resolver.MemberIdResolver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

@Value("${webmvc.cors.allowedOrigins}")
private String allowedOrigins;

private final MemberIdResolver memberIdResolver;


@Bean
public WebMvcConfigurer corsConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(allowedOrigins.split(","))
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
};
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(memberIdResolver);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.layer.domain.auth.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.layer.domain.auth.controller.dto.*;
import org.layer.domain.auth.service.dto.SignInServiceResponse;
import org.layer.domain.auth.service.dto.SignUpServiceResponse;
import org.layer.oauth.service.GoogleService;
import org.layer.oauth.service.KakaoService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.layer.domain.auth.service.AuthService;
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/api/auth")
@RestController
public class AuthController {
private final AuthService authService;
private final GoogleService googleService;
private final KakaoService kakaoService;

// 로그인
@PostMapping("/sign-in")
public ResponseEntity<SignInResponse> signIn(@RequestHeader("Authorization") final String socialAccessToken, @RequestBody final SignInRequest signInRequest) {
SignInServiceResponse signInServiceResponse = authService.signIn(socialAccessToken, signInRequest.socialType());
return new ResponseEntity<>(SignInResponse.of(signInServiceResponse), HttpStatus.OK);
}

// 회원가입 => 소셜로그인 했는데 유효한 유저가 없을 때 이름 입력하고 회원가입하는 과정
@PostMapping("/sign-up")
public ResponseEntity<SignUpResponse> signUp(@RequestHeader("Authorization") final String socialAccessToken, @RequestBody final SignUpRequest signUpRequest) {
SignUpServiceResponse signUpServiceResponse = authService.signUp(socialAccessToken, signUpRequest);
return new ResponseEntity<>(SignUpResponse.of(signUpServiceResponse), HttpStatus.CREATED);
}


// 로그아웃
@PostMapping("/sign-out")
public ResponseEntity<?> signOut(@RequestBody Long memberId) {
authService.signOut(memberId);
return new ResponseEntity<>(HttpStatus.OK);
}

// 회원 탈퇴
@PostMapping("/withdraw")
public ResponseEntity<?> withdraw(@RequestBody Long memberId) {
authService.withdraw(memberId);
return new ResponseEntity<>(HttpStatus.OK); // TODO: 리턴 객체 수정 필요
}

// 토큰 재발급
@PostMapping("/reissue-token")
public ResponseEntity<ReissueTokenResponse> reissueToken(@RequestBody Long memberId) {
return new ResponseEntity<>(
ReissueTokenResponse.of(authService.reissueToken(memberId)),
HttpStatus.CREATED);
}

//== google OAuth2 test용 API 액세스 토큰 발급 ==//
@GetMapping("oauth2/google")
public String googleTest(@RequestParam("code") String code) {
return googleService.getToken(code);
}

//== kakao OAuth2 test용 API 액세스 토큰 발급 ==//
@GetMapping("oauth2/kakao")
public Object kakaoLogin(@RequestParam(value = "code", required = false) String code) {
return kakaoService.getToken(code);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.layer.domain.auth.controller.dto;

import org.layer.domain.auth.service.dto.ReissueTokenServiceResponse;

public record ReissueTokenResponse(Long memberId, String accessToken, String refreshToken){
public static ReissueTokenResponse of(ReissueTokenServiceResponse rtsr) {
return new ReissueTokenResponse(rtsr.memberId(),
rtsr.jwtToken().getAccessToken(),
rtsr.jwtToken().getRefreshToken());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.layer.domain.auth.controller.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.layer.domain.member.entity.SocialType;

public record SignInRequest(@JsonProperty("social_type") SocialType socialType) {
}
Loading

0 comments on commit 332a261

Please sign in to comment.