Skip to content

Commit 9f6595a

Browse files
committed
feat: SecurityConfig 내용 추가, 수정, 컨트롤러 내용 일부 수정 및 principal에 저장 적용
1 parent e125580 commit 9f6595a

File tree

4 files changed

+76
-12
lines changed

4 files changed

+76
-12
lines changed
Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
package cmf.commitField.domain.user.controller;
22

3-
import org.springframework.security.core.annotation.AuthenticationPrincipal;
3+
import org.springframework.http.HttpStatus;
4+
import org.springframework.http.ResponseEntity;
5+
import org.springframework.security.core.Authentication;
6+
import org.springframework.security.core.context.SecurityContextHolder;
7+
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
48
import org.springframework.security.oauth2.core.user.OAuth2User;
59
import org.springframework.web.bind.annotation.GetMapping;
610
import org.springframework.web.bind.annotation.RestController;
711

8-
import java.util.Map;
9-
1012
@RestController
1113
public class AuthController {
12-
@GetMapping("/user")
13-
public Map<String, Object> user(@AuthenticationPrincipal OAuth2User principal) {
14-
return principal.getAttributes(); // 사용자 정보 반환
14+
15+
@GetMapping("/login")
16+
public ResponseEntity<?> user() {
17+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
18+
19+
if (authentication instanceof OAuth2AuthenticationToken) {
20+
OAuth2User principal = (OAuth2User) authentication.getPrincipal();
21+
return ResponseEntity.ok(principal.getAttributes()); // 사용자 정보 반환
22+
}
23+
24+
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("로그인이 필요합니다.");
1525
}
16-
}
26+
}

src/main/java/cmf/commitField/global/security/SecurityConfig.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,66 @@
44
import org.springframework.context.annotation.Configuration;
55
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
66
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
7+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
8+
import org.springframework.security.config.http.SessionCreationPolicy;
9+
import org.springframework.security.core.context.SecurityContextHolder;
10+
import org.springframework.security.oauth2.core.user.OAuth2User;
711
import org.springframework.security.web.SecurityFilterChain;
812

913
@Configuration
1014
@EnableWebSecurity
1115
public class SecurityConfig {
1216
@Bean
1317
protected SecurityFilterChain config(HttpSecurity http) throws Exception {
18+
19+
//로그인 관련 설정
1420
http
1521
.oauth2Login(oauth2 -> oauth2
1622
.loginPage("/login") // 로그인 페이지 지정
23+
.successHandler((request, response, authentication) -> {
24+
// 인증 정보가 SecurityContext에 추가되는 것을 보장
25+
SecurityContextHolder.getContext().setAuthentication(authentication);
26+
27+
// 디버깅: authentication 정보 확인
28+
System.out.println("Authentication: " + authentication);
29+
System.out.println("Principal: " + authentication.getPrincipal());
30+
31+
if (authentication != null && authentication.getPrincipal() != null) {
32+
//인가가 있으면 유저 정보를 저장
33+
OAuth2User principal = (OAuth2User) authentication.getPrincipal();
34+
String username = principal.getAttribute("login");
35+
36+
// 세션에 사용자 정보를 추가
37+
request.getSession().setAttribute("user", username);
38+
39+
response.sendRedirect("/"); // 로그인 성공 후 리다이렉트
40+
} else {
41+
// 인증 실패 시 처리
42+
response.sendRedirect("/login?error=authenticationFailed");
43+
}
44+
})
45+
)
46+
.sessionManagement(session -> session
47+
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // 세션 정책 설정
48+
.invalidSessionUrl("/login?error=invalidSession") // 세션이 유효하지 않으면 이동할 URL
49+
.maximumSessions(1) // 하나의 계정으로 한 번에 로그인할 수 있도록 제한
50+
.expiredUrl("/login?error=sessionExpired") // 세션 만료 후 이동할 URL 설정
1751
);
52+
53+
//로그아웃 관련 설정
54+
http
55+
.logout(logout -> logout
56+
.logoutUrl("/logout") // 로그아웃 URL 설정
57+
.logoutSuccessUrl("/") // 로그아웃 성공 후 이동할 URL
58+
.invalidateHttpSession(true) // 로그아웃 시 세션 무효화
59+
.clearAuthentication(true) // 인증 정보 지우기
60+
.deleteCookies("JSESSIONID") // 세션 쿠키 삭제
61+
);
62+
http
63+
.csrf(
64+
AbstractHttpConfigurer::disable // CSRF 보호 비활성화
65+
);
66+
1867
return http.build();
1968
}
2069
}
1.12 KB
Binary file not shown.

src/main/resources/static/index.html

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
<body>
99
<h1>GitHub OAuth2 로그인 테스트</h1>
1010

11-
<a href="/oauth2/authorization/github">
11+
<!-- 로그인 버튼 -->
12+
<a href="/oauth2/authorization/github" id="loginBtn" style="display: none;">
1213
<button>GitHub 로그인</button>
1314
</a>
1415

16+
<!-- 로그아웃 버튼 -->
1517
<button id="logoutBtn" style="display: none;">로그아웃</button>
1618

1719
<h2>사용자 정보</h2>
@@ -20,23 +22,26 @@ <h2>사용자 정보</h2>
2022
<script>
2123
async function fetchUser() {
2224
try {
23-
const response = await fetch('/user');
25+
const response = await fetch('/login');
2426
if (!response.ok) throw new Error("Not logged in");
2527

2628
const data = await response.json();
2729
document.getElementById("userInfo").textContent = JSON.stringify(data, null, 2);
2830
document.getElementById("logoutBtn").style.display = "block";
31+
document.getElementById("loginBtn").style.display = "none";
2932
} catch (error) {
3033
document.getElementById("userInfo").textContent = "로그인이 필요합니다.";
34+
document.getElementById("logoutBtn").style.display = "none";
35+
document.getElementById("loginBtn").style.display = "inline-block";
3136
}
3237
}
3338

3439
document.getElementById("logoutBtn").addEventListener("click", async () => {
35-
await fetch('/logout', { method: 'GET' });
36-
location.reload();
40+
await fetch('/logout', { method: 'POST' }); // POST 방식으로 로그아웃
41+
fetchUser(); // 로그아웃 후 사용자 정보 갱신
3742
});
3843

39-
fetchUser();
44+
fetchUser(); // 페이지 로드 시 사용자 정보 가져오기
4045
</script>
4146
</body>
4247
</html>

0 commit comments

Comments
 (0)