mirror of
https://github.com/headporter81/specialsource-homepage-backend.git
synced 2026-08-08 15:41:11 +09:00
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package company.specialsource.config; // 본인의 패키지 경로에 맞게 수정하세요
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtException;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
public class JwtTokenProvider {
|
||||
|
||||
private final SecretKey key;
|
||||
private final long expirationTime;
|
||||
|
||||
// application.yml에 적은 설정값들을 생성자를 통해 주입받습니다.
|
||||
public JwtTokenProvider(
|
||||
@Value("${jwt.secret}") String secretKey,
|
||||
@Value("${jwt.expiration-time}") long expirationTime) {
|
||||
|
||||
// Base64로 인코딩된 비밀키를 디코딩하여 실제 암호화 키 객체로 변환합니다.
|
||||
byte[] keyBytes = Decoders.BASE64.decode(secretKey);
|
||||
this.key = Keys.hmacShaKeyFor(keyBytes);
|
||||
this.expirationTime = expirationTime;
|
||||
}
|
||||
|
||||
// 1. 유저 이름을 받아서 JWT 토큰을 생성하는 메서드
|
||||
public String createToken(String username) {
|
||||
Date now = new Date();
|
||||
Date validity = new Date(now.getTime() + expirationTime);
|
||||
|
||||
return Jwts.builder()
|
||||
.subject(username) // 토큰의 주인(주체) 저장
|
||||
.issuedAt(now) // 토큰 발행 시간
|
||||
.expiration(validity) // 토큰 만료 시간
|
||||
.signWith(key) // 내 서버의 비밀키로 서명(Signature) 생성
|
||||
.compact();
|
||||
}
|
||||
|
||||
// 2. 토큰에서 유저 이름(Subject)을 꺼내는 메서드
|
||||
public String getUsername(String token) {
|
||||
Claims claims = Jwts.parser()
|
||||
.verifyWith(key) // 내 비밀키로 서명을 검증한 뒤
|
||||
.build()
|
||||
.parseSignedClaims(token)
|
||||
.getPayload(); // 데이터 덩어리를 꺼냄
|
||||
|
||||
return claims.getSubject();
|
||||
}
|
||||
|
||||
// 3. 토큰이 유효한지(만료되진 않았는지, 위조되진 않았는지) 검증하는 메서드
|
||||
public boolean validateToken(String token) {
|
||||
try {
|
||||
Jwts.parser()
|
||||
.verifyWith(key)
|
||||
.build()
|
||||
.parseSignedClaims(token);
|
||||
return true; // 아무 에러도 안 나면 정상적인 토큰!
|
||||
} catch (JwtException | IllegalArgumentException e) {
|
||||
// 토큰이 만료되었거나, 위조되었거나, 형식이 잘못되었을 때 여기로 빠집니다.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,39 @@
|
||||
package company.specialsource.controller;
|
||||
|
||||
import company.specialsource.config.JwtTokenProvider;
|
||||
import company.specialsource.dto.LoginRequest;
|
||||
import company.specialsource.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
@RequiredArgsConstructor
|
||||
@RequiredArgsConstructor // 롬복이 jwtTokenProvider와 userService의 생성자를 자동으로 만들어줍니다.
|
||||
public class AuthController {
|
||||
|
||||
private final UserService userService;
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final UserService userService; // 실제 서비스 주입
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<String> login(@RequestBody LoginRequest loginRequest) {
|
||||
boolean isSuccess = userService.login(loginRequest.getUsername(), loginRequest.getPassword());
|
||||
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
|
||||
|
||||
if (isSuccess) {
|
||||
return ResponseEntity.ok("로그인 성공!!!");
|
||||
} else {
|
||||
return ResponseEntity.status(401).body("아이디 또는 비밀번호가 틀렸습니다.");
|
||||
// 1. 기존 하드코딩("admin", "1234") 대신 실제 DB를 조회하는 서비스 메서드 호출
|
||||
if (userService.login(request.getUsername(), request.getPassword())) {
|
||||
|
||||
// 2. 로그인 성공 시, 입력받은 username으로 JWT 토큰 생성
|
||||
String token = jwtTokenProvider.createToken(request.getUsername());
|
||||
|
||||
// 3. 응답 상자에 토큰을 담아서 리턴
|
||||
Map<String, String> response = new HashMap<>();
|
||||
response.put("token", token);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
// 4. DB에 유저가 없거나 비밀번호가 틀리면 401 반환
|
||||
return ResponseEntity.status(401).body("아이디 또는 비밀번호가 틀렸습니다.");
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
package company.specialsource.dto;
|
||||
package company.specialsource.dto; // 패키지 위치에 맞게 조정하세요
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter @Setter
|
||||
public class LoginRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
// Getter, Setter (인텔리제이에서 롬복 @Getter, @Setter 쓰셔도 됩니다!)
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
}
|
||||
@@ -15,4 +15,10 @@ spring:
|
||||
|
||||
jasypt:
|
||||
encryptor:
|
||||
password: 81sungjin1015
|
||||
password: 81sungjin1015
|
||||
|
||||
jwt:
|
||||
# 256비트 이상이어야 하므로 영문+숫자 (최소 32글자 이상)
|
||||
secret: c3ByaW5nYm9vdC1qd3Qtc2VjcmV0LWtleS1zcGVjaWFsc291cmNlLWhvbWVwYWdlLWJhY2tlbmQtMjAyNg==
|
||||
# 토큰 유효 시간 (1시간으로 설정 = 60분 * 60초 * 1000밀리초)
|
||||
expiration-time: 3600000
|
||||
Reference in New Issue
Block a user