Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8주차 미션 / 서버4조 조규빈 #21

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public WebConfig(AuthInterceptor authInterceptor) {

@Override
public void addInterceptors(InterceptorRegistry registry) {
// TODO /profile, /admin 앞에 붙이기
registry.addInterceptor(authInterceptor)
.addPathPatterns("/profile/**", "/admin/**");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.kuit.kuit4serverauth.model.User;
import com.kuit.kuit4serverauth.repository.UserRepository;
import com.kuit.kuit4serverauth.service.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -14,16 +16,12 @@
import java.util.HashMap;
import java.util.Map;

@RequiredArgsConstructor
@RestController
public class AuthController {
private final UserRepository userRepository;
private final JwtUtil jwtUtil;

public AuthController(UserRepository userRepository, JwtUtil jwtUtil) {
this.userRepository = userRepository;
this.jwtUtil = jwtUtil;
}

@PostMapping("/login")
public ResponseEntity<Map<String, String>> login(@RequestBody Map<String, String> credentials) {
String username = credentials.get("username");
Expand All @@ -35,9 +33,40 @@ public ResponseEntity<Map<String, String>> login(@RequestBody Map<String, String
}

String token = jwtUtil.generateToken(user.getUsername(), user.getRole());
String refreshToken = jwtUtil.generateRefreshToken(user.getUsername(), user.getRole());
Map<String, String> response = new HashMap<>();
response.put("token", token);
response.put("refreshToken", refreshToken);

return ResponseEntity.ok(response);
}

// RefreshToken을 사용해 AccessToken 재발급
@PostMapping("/refresh-token")
public ResponseEntity<Map<String, String>> refreshAccessToken(@RequestBody Map<String, String> credentials) {
String refreshToken = credentials.get("refreshToken");

try {
// RefreshToken 유효성 검사 및 AccessToken 재발급
Claims claims = jwtUtil.validateToken(refreshToken);
String username = claims.getSubject();
String role = claims.get("role", String.class);

if (role != null && role.equals("ROLE_ADMIN")) {
role = "admin";
} else {
role = "user";
}

String newAccessToken = jwtUtil.generateToken(username, role); // Role은 실제 사용자 role에 맞게 설정

Map<String, String> response = new HashMap<>();
response.put("accessToken", newAccessToken);

return ResponseEntity.ok(response);
} catch (Exception e) {
throw new CustomException(ErrorCode.INVALID_TOKEN);
}
}
}

Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@
package com.kuit.kuit4serverauth.controller;

import com.kuit.kuit4serverauth.service.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
public class UserController {

private final JwtUtil jwtUtil;

@GetMapping("/profile")
public ResponseEntity<String> getProfile(HttpServletRequest request) {
// TODO : 로그인 한 사용자면 username 이용해 "Hello, {username}" 반환하기
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");

String token = extractToken(request);
if (token == null || (jwtUtil.validateToken(token) == null)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
}

Claims claims = jwtUtil.validateToken(token);
String username = claims.getSubject();

return ResponseEntity.ok("Hello, " + username);
}

@GetMapping("/admin")
public ResponseEntity<String> getAdmin(HttpServletRequest request) {
// TODO: role이 admin이면 "Hello, admin" 반환하기
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Forbidden");
String token = extractToken(request);
if (token == null || (jwtUtil.validateToken(token) == null)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
}

Claims claims = jwtUtil.validateToken(token);
String role = claims.get("role", String.class);

if (role != null && role.equals("ROLE_ADMIN")) {
return ResponseEntity.ok("Hello, admin");
} else {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Forbidden");
}
}

private String extractToken(HttpServletRequest request) {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
return authorizationHeader.substring(7); // Remove "Bearer " prefix
}
return null;
}
}
39 changes: 34 additions & 5 deletions src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,58 @@
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
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 JwtUtil {
private final String secret = "mysecretkey";
private final long expirationMs = 3600000; // 1 hour
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.accessExpiration}")
private Long accessExpirationMs; // 1 hour
@Value("${jwt.refreshExporation}")
private Long refreshExpirationMs; // 24 hour

private final SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);


public String generateToken(String username, String role) {
return Jwts.builder()
.setSubject(username)
.claim("role", role)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + expirationMs))
.signWith(SignatureAlgorithm.HS256, secret)
.setExpiration(new Date(System.currentTimeMillis() + accessExpirationMs))
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}

// RefreshToken 발급
public String generateRefreshToken(String username, String role) {
return Jwts.builder()
.setSubject(username)
.claim("role", role)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + refreshExpirationMs))
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}

// RefreshToken으로 AccessToken 재발급
public String refreshAccessToken(String refreshToken) {
Claims claims = validateToken(refreshToken);
String username = claims.getSubject();
String role = claims.get("role", String.class);
return generateToken(username, role); // 새로운 AccessToken 발급
}

public Claims validateToken(String token) {
try {
return Jwts.parser()
.setSigningKey(secret)
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ spring:

jwt:
secret: mysecretkey
expiration: 3600000

accessExpiration: 3600000
refreshExporation: 86400000