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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
# Be
# Be



### 아키텍처
<img width="1394" alt="image" src="https://github.com/user-attachments/assets/e9e6062c-ad13-42cb-9cf5-db85858c1657" />
5 changes: 1 addition & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ dependencies {

// DB
runtimeOnly 'com.mysql:mysql-connector-j'
implementation 'com.h2database:h2'


// Lombok
compileOnly 'org.projectlombok:lombok'
Expand All @@ -52,8 +50,7 @@ dependencies {
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6'
}

tasks.named('test') {
Expand Down
3 changes: 1 addition & 2 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ http {
server {
listen 80;
return 301 https://api.neodinary.store$request_uri;
return ;
}

server {
listen 443 ssl;
server_name api.neodinary.store;

ssl_certificate /etc/letsencrypt/live/api.neodinary.store/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/liveapi.neodinary.store/privkey.pem;
ssl_certificate_key /etc/letsencrypt/live/api.neodinary.store/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public ActivityResponseDto getActivity(Long activityId) {
}

public void addUserActivities(Long userId, ActivityNewRequestDto.AddActivity request) {
User user = userRepository.findById(userId)
User user = userRepository.findByKakaoId(userId)
.orElseThrow(() -> new BusinessException(Code.USER_NOT_FOUND, "이미 오늘 참여한 활동입니다."));

Category category = categoryRepository.findByCategoryType(request.getCategoryType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
@Getter
@AllArgsConstructor
public class UserProfileDto {
private Long id;

private Long kakaoId;
private String nickname;
private String role;

public UserProfileDto(User user) {
this.id = user.getId();
this.kakaoId = user.getKakaoId();
this.nickname = user.getName();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,23 @@ public class User extends BaseEntity {
@Comment("회원 고유값")
private Long id;

@Column(name = "KAKAO_ID", unique = true, nullable = false)
@Comment("카카오 ID")
private Long kakaoId;

@Column(name = "NAME", nullable = false, length = 50)
@Comment("이름")
private String name;

@Column(name = "email", nullable = false, unique = true)
private String email;

@Enumerated(EnumType.STRING)
@Column(name = "PROVIDER", nullable = false, length = 10)
@Comment("소셜 로그인 제공자")
private OAuthProvider oauthProvider;


@Column(name = "REG_ID", nullable = false, length = 50)
@Comment("등록자")
private String regId;


@Column(name = "UPD_ID", length = 50)
@Comment("수정자")
private String updId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findById(Long id);

Optional<User> findByKakaoId(Long kakaoId);
}

Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ public class UserService {
private final UserRepository userRepository;

public User findOrCreate(KakaoUserInfoDto userInfo) {
return userRepository.findById(userInfo.getId())
return userRepository.findByKakaoId(userInfo.getId())
.orElseGet(() -> userRepository.save(userInfo.toEntity()));
}

public UserProfileDto getProfile(Long email) {
User user = userRepository.findById(email)
public UserProfileDto getProfile(Long id) {
User user = userRepository.findByKakaoId(id)
.orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다."));
return new UserProfileDto(user);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ public KakaoUserInfoDto(

public User toEntity() {
return User.builder()
.id(id)
.kakaoId(id)
.name(name)
.oauthProvider(KAKAO)
.regId(String.valueOf(id))
.build();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ public String loginWithKakao(String code) {
log.info("userInfo : {}", userInfo);

// 3. 회원 조회 또는 저장
User user = userRepository.findById(userInfo.getId())
User user = userRepository.findByKakaoId(userInfo.getId())
.orElseGet(() -> userRepository.save(userInfo.toEntity()));

// 4. JWT 토큰 발급
return jwtUtil.generateToken(user.getId());
return jwtUtil.generateToken(user.getKakaoId());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
// ✅ 경로별 접근 권한 설정
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/",
"/swagger-ui/**",
"/swagger-ui.html",
"/v3/api-docs/**",
"/auth/**", // 소셜 로그인 콜백
"/login", // 혹시 사용할 경우
"/health", // 헬스 체크
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
package com.example.hackathon.global.config;

import io.swagger.v3.oas.models.OpenAPI;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.servers.Server;

import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.Components;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SwaggerConfig {

private static final String SECURITY_SCHEME_NAME = "JWT";

@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(apiInfo())
.addServersItem(new Server().url("/"));
.addServersItem(new Server().url("/"))
.components(new Components()
.addSecuritySchemes(SECURITY_SCHEME_NAME,
new SecurityScheme()
.name(SECURITY_SCHEME_NAME)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
)
)
.addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME));
}

private Info apiInfo() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public Object resolveArgument(
String token = ((HttpServletRequest) webRequest.getNativeRequest())
.getHeader("Authorization");

if (token == null || token.isBlank()) {
return null;
}

// JWT 파싱 → userId 추출
return jwtUtil.getUserIdFromToken(token);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected void doFilterInternal(
if (token != null && jwtUtil.validateToken(token)) {
String id = jwtUtil.extractKakaoId(token);

User user = userRepository.findById(Long.valueOf(id))
User user = userRepository.findByKakaoId(Long.valueOf(id))
.orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다: " + id));

// 인증 객체 생성 (권한 정보는 생략하거나 필요시 추가)
Expand Down
8 changes: 4 additions & 4 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ spring:
server:
port: 8080
datasource:
url: jdbc:mysql://${DEFAULT_URL}?serverTimezone=UTC
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
url: jdbc:mysql://${PROD_DB_ENDPOINT}:3306/${PROD_DB_NAME}?serverTimezone=UTC
username: ${PROD_DB_USERNAME}
password: ${PROD_DB_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
ddl-auto: create
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
Expand Down