Skip to content

Commit 47bd88d

Browse files
authored
[feat] 데모용 로그인 기능 (#3)
* feat: demo-login 버튼 및 api 연동 * feat: demo login api * chore: 주석 정리
1 parent 35b37ea commit 47bd88d

File tree

7 files changed

+113
-23
lines changed

7 files changed

+113
-23
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.timepaper.backend.domain.user.controller;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.timepaper.backend.domain.user.entity.User;
5+
import com.timepaper.backend.global.auth.service.AuthService;
6+
import com.timepaper.backend.global.common.dto.ApiResponse;
7+
import jakarta.servlet.http.HttpServletResponse;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.beans.factory.annotation.Value;
10+
import org.springframework.http.HttpStatus;
11+
import org.springframework.http.ResponseEntity;
12+
import org.springframework.security.authentication.AuthenticationManager;
13+
import org.springframework.security.authentication.BadCredentialsException;
14+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
15+
import org.springframework.security.core.Authentication;
16+
import org.springframework.web.bind.annotation.PostMapping;
17+
import org.springframework.web.bind.annotation.RequestMapping;
18+
import org.springframework.web.bind.annotation.RestController;
19+
20+
import java.io.IOException;
21+
22+
@RestController
23+
@RequiredArgsConstructor
24+
@RequestMapping("/api")
25+
public class DemoLoginController {
26+
27+
private final AuthenticationManager authenticationManager;
28+
private final AuthService authService;
29+
private final ObjectMapper objectMapper;
30+
@Value("${DEMO_EMAIL}")
31+
private String demoEmail;
32+
@Value("${DEMO_PASSWORD}")
33+
private String demoPassword;
34+
35+
@PostMapping("/auth/demo-login")
36+
public ResponseEntity<?> demoLogin(HttpServletResponse response) throws IOException {
37+
UsernamePasswordAuthenticationToken authToken =
38+
new UsernamePasswordAuthenticationToken(demoEmail, demoPassword);
39+
40+
try {
41+
Authentication authentication = authenticationManager.authenticate(authToken);
42+
User user = (User) authentication.getPrincipal();
43+
44+
// 로그인 성공 시 토큰 설정
45+
authService.setTokensResponse(response, authentication, user.getId());
46+
47+
return ResponseEntity.ok().body(ApiResponse.ok("데모 로그인 성공"));
48+
49+
} catch (BadCredentialsException e) {
50+
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
51+
.body(ApiResponse.error("유효하지 않은 데모 로그인 정보입니다.", "DEMO_LOGIN_FAIL"));
52+
}
53+
}
54+
}

backend/src/main/java/com/timepaper/backend/global/security/config/SecurityPathConfig.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
public class SecurityPathConfig {
44

5-
public static final String[] PUBLIC_GET_URLS = {
6-
"/api/timepapers/**"
7-
};
5+
public static final String[] PUBLIC_GET_URLS = {
6+
"/api/timepapers/**"
7+
};
88

9-
public static final String[] PUBLIC_POST_URLS = {
10-
"/api/auth/login",
11-
"/api/auth/signup",
12-
"/api/auth/reissue",
13-
"/api/auth/email-verification-codes",
14-
"/api/auth/email-verification-codes/validate"
15-
};
9+
public static final String[] PUBLIC_POST_URLS = {
10+
"/api/auth/login",
11+
"/api/auth/signup",
12+
"/api/auth/reissue",
13+
"/api/auth/email-verification-codes",
14+
"/api/auth/email-verification-codes/validate",
15+
"/api/auth/demo-login",
16+
};
1617

1718
}

frontend/src/api/api.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ export const api = {
1717
return response;
1818
},
1919

20+
demoLogin: async () => {
21+
return await apiInstance.post('/auth/demo-login',{},{ withCredentials: true,},);
22+
},
23+
2024
reissue: async () => {
2125
const response = await apiInstance.post(
2226
'/auth/reissue',

frontend/src/api/apiInstance.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const NO_TOKEN_REQUIRED = [
1212
'/auth/signup',
1313
'/auth/email-verification-codes',
1414
'/auth/email-verification-codes/validate',
15+
'/auth/demo-login',
1516
];
1617

1718
const GET_TIMEPAPER_REGEX = /^\/timepapers\/\d+$/;

frontend/src/pages/login/Login.jsx

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,20 @@ export default function Login() {
1818
const location = useLocation();
1919
const { isLoggedIn } = useSelector((state) => state.auth);
2020

21+
const handleLoginSuccess = (response) => {
22+
dispatch(login(response.headers.authorization));
23+
const next = location.state?.next ?? -1;
24+
navigate(next, { replace: true });
25+
};
26+
2127
const handleLoginButtonClick = (event) => {
2228
setIsLoginButtonEnable(false);
2329
event.preventDefault();
2430
(async () => {
2531
dispatch(startLoading());
2632
try {
2733
const response = await api.login(inputData.email, inputData.password);
28-
dispatch(login(response.headers.authorization));
29-
const next = location.state?.next ?? -1;
30-
navigate(next, { replace: true });
34+
handleLoginSuccess(response);
3135
} catch (error) {
3236
setIsAlertShow(true);
3337
setIsLoginButtonEnable(true);
@@ -37,6 +41,19 @@ export default function Login() {
3741
})();
3842
};
3943

44+
const handleDemoLoginButtonClick = async (event) => {
45+
event.preventDefault();
46+
try {
47+
const response = await api.demoLogin();
48+
handleLoginSuccess(response);
49+
} catch (error) {
50+
setIsAlertShow(true);
51+
setIsLoginButtonEnable(true);
52+
} finally {
53+
dispatch(finishLoading());
54+
}
55+
};
56+
4057
const handleInputChange = (event) => {
4158
setIntputData((prev) => ({
4259
...prev,
@@ -72,11 +89,11 @@ export default function Login() {
7289
<>
7390
<div className={styles.container}>
7491
{isAlertShow && (
75-
<Alert
76-
buttonTitle={'확인'}
77-
message={'로그인 실패했습니다.'}
78-
onClick={handleAlertButtonClick}
79-
></Alert>
92+
<Alert
93+
buttonTitle={'확인'}
94+
message={'로그인 실패했습니다.'}
95+
onClick={handleAlertButtonClick}
96+
></Alert>
8097
)}
8198
<img src={staticImagePath.timepaperLogo} className="logo-image" />
8299
<form action="" className={styles.formContainer}>
@@ -104,6 +121,9 @@ export default function Login() {
104121
<button className={styles.signupButton} onClick={handleSignUpButtonClick}>
105122
회원가입
106123
</button>
124+
<button className={styles.demoLoginButton} onClick={handleDemoLoginButtonClick}>
125+
데모 로그인
126+
</button>
107127
</div>
108128
</form>
109129
</div>

frontend/src/pages/login/Login.module.css

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
}
3535

3636
.inputId.inputPassword::placeholder {
37-
color: #B1B1B1;
37+
color: #b1b1b1;
3838
font-family: var(--pretendard-regular);
3939
font-size: 17px;
4040
}
@@ -50,11 +50,23 @@
5050
.signupButton {
5151
width: 90%;
5252
height: 55px;
53-
background-color: #D9D9D9;
53+
background-color: #d9d9d9;
5454
margin-top: 3%;
5555
border: none;
5656
border-radius: 10px;
5757
font-family: var(--pretendard-regular);
5858
font-size: 17px;
5959
cursor: pointer;
60-
}
60+
}
61+
62+
.demoLoginButton {
63+
width: 90%;
64+
height: 55px;
65+
background-color: #85d4e1;
66+
margin-top: 3%;
67+
border: none;
68+
border-radius: 10px;
69+
font-family: var(--pretendard-regular);
70+
font-size: 17px;
71+
cursor: pointer;
72+
}

frontend/src/pages/signup/SignUp.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,6 @@ export default function SignUp() {
137137
}));
138138
setPassword(value);
139139

140-
console.log(value)
141-
console.log(check.test(value) && value.length >= 8)
142140
};
143141

144142
const handlePasswordCheck = (e) => {

0 commit comments

Comments
 (0)