mirror of
https://github.com/headporter81/specialsource-homepage-backend.git
synced 2026-08-08 15:41:11 +09:00
nitial commit
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package company.specialsource;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpecialsourceHomepageApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpecialsourceHomepageApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package company.specialsource.config;
|
||||
|
||||
import company.specialsource.entity.User;
|
||||
import company.specialsource.repository.UserRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j; // 로그를 위해 추가
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j // 로그 라이브러리
|
||||
public class DataInitializer implements CommandLineRunner {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
if (userRepository.findByUsername("admin").isEmpty()) {
|
||||
userRepository.save(User.builder()
|
||||
.username("admin")
|
||||
.password(passwordEncoder.encode("1234"))
|
||||
.role("ROLE_USER")
|
||||
.build());
|
||||
log.info("초기 관리자 계정(admin)이 생성되었습니다.");
|
||||
} else {
|
||||
log.info("이미 관리자 계정이 존재합니다.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package company.specialsource.config;
|
||||
|
||||
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
|
||||
import org.jasypt.encryption.StringEncryptor;
|
||||
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
|
||||
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableEncryptableProperties
|
||||
public class JasyptConfig {
|
||||
|
||||
@Value("${jasypt.encryptor.password}")
|
||||
private String password;
|
||||
|
||||
@Bean("jasyptStringEncryptor")
|
||||
public StringEncryptor stringEncryptor() {
|
||||
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
|
||||
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
|
||||
config.setPassword(password); // 암호화 키 (절대 외부에 유출 금지!)
|
||||
config.setAlgorithm("PBEWithMD5AndDES");
|
||||
config.setKeyObtentionIterations("1000");
|
||||
config.setPoolSize("1");
|
||||
config.setProviderName("SunJCE");
|
||||
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
|
||||
config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
|
||||
config.setStringOutputType("base64");
|
||||
encryptor.setConfig(config);
|
||||
return encryptor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package company.specialsource.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf(csrf -> csrf.disable()) // REST API 통신을 위해 CSRF 비활성화
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/api/login").permitAll() // 로그인 API는 누구나 접근 가능
|
||||
.anyRequest().authenticated()
|
||||
);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder(); // BCrypt 암호화 알고리즘 사용
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package company.specialsource.controller;
|
||||
|
||||
import company.specialsource.dto.LoginRequest;
|
||||
import company.specialsource.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthController {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<String> login(@RequestBody LoginRequest loginRequest) {
|
||||
boolean isSuccess = userService.login(loginRequest.getUsername(), loginRequest.getPassword());
|
||||
|
||||
if (isSuccess) {
|
||||
return ResponseEntity.ok("로그인 성공!");
|
||||
} else {
|
||||
return ResponseEntity.status(401).body("아이디 또는 비밀번호가 틀렸습니다.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package company.specialsource.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter @Setter
|
||||
public class LoginRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package company.specialsource.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users") // PostgreSQL에서 'user'는 예약어이므로 'users' 테이블 명칭 권장
|
||||
@Getter
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(unique = true, nullable = false)
|
||||
private String username;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String password;
|
||||
|
||||
private String role; // 예: ROLE_USER, ROLE_ADMIN
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package company.specialsource.repository;
|
||||
|
||||
import company.specialsource.entity.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
// 사용자 아이디로 정보를 찾아오는 메서드
|
||||
Optional<User> findByUsername(String username);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package company.specialsource.service;
|
||||
|
||||
import company.specialsource.entity.User;
|
||||
import company.specialsource.repository.UserRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
public boolean login(String username, String password) {
|
||||
Optional<User> userOptional = userRepository.findByUsername(username);
|
||||
|
||||
if (userOptional.isPresent()) {
|
||||
User user = userOptional.get();
|
||||
// DB의 암호화된 비번과 입력받은 평문 비번 비교
|
||||
return passwordEncoder.matches(password, user.getPassword());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:postgresql://192.168.0.215:5435/mydb
|
||||
username: headporter
|
||||
password: ENC(Gg03NzjjcVOrFSXoBrPEusNgDNbYOPO4)
|
||||
driver-class-name: org.postgresql.Driver
|
||||
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: update # 테이블 자동 생성
|
||||
show-sql: true # SQL 로그 출력
|
||||
properties:
|
||||
hibernate:
|
||||
format_sql: true
|
||||
|
||||
jasypt:
|
||||
encryptor:
|
||||
password: 81sungjin1015
|
||||
@@ -0,0 +1,2 @@
|
||||
$env:JASYPT_ENCRYPTOR_PASSWORD="81sungjin1015"
|
||||
./gradlew bootRun
|
||||
Reference in New Issue
Block a user