feat : 로그인 기능 구현
SpecialSource Frontend CD / deploy (push) Successful in 9s

This commit is contained in:
2026-05-26 13:19:36 +09:00
parent eb7de0fc11
commit 671f53f428
5 changed files with 9 additions and 11 deletions
+1
View File
@@ -0,0 +1 @@
VITE_API_URL=
+1
View File
@@ -0,0 +1 @@
VITE_API_URL=http://192.168.0.215:18080
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

+6 -10
View File
@@ -63,7 +63,7 @@
class="login-input" class="login-input"
placeholder="ENTER ACCESS ID" placeholder="ENTER ACCESS ID"
@keyup.enter="handleLoginSubmit" @keyup.enter="handleLoginSubmit"
/> >
</div> </div>
<div class="login-input-group"> <div class="login-input-group">
<label class="login-label">ACCESS KEY_</label> <label class="login-label">ACCESS KEY_</label>
@@ -133,8 +133,8 @@ const terminalRef = ref(null);
const termInstance = ref(null); const termInstance = ref(null);
// 로그인 폼 양방향 바인딩 변수 // 로그인 폼 양방향 바인딩 변수
const loginId = ref(''); const loginId = ref('admin');
const loginPw = ref(''); const loginPw = ref('1234');
// 메뉴 및 인증 토큰 반응형 변수화 // 메뉴 및 인증 토큰 반응형 변수화
const activeMenu = ref('main'); const activeMenu = ref('main');
@@ -197,31 +197,27 @@ const handleLoginSubmit = async () => {
} }
try { try {
// 백엔드 포트인 18080 서버로 인증 요청을 전송합니다. const apiBaseUrl = import.meta.env.VITE_API_URL || '';
const response = await axios.post('http://192.168.0.215:18080/api/auth/login', {
const response = await axios.post(`${apiBaseUrl}/api/login`, {
username: loginId.value, username: loginId.value,
password: loginPw.value password: loginPw.value
}); });
if (response.data && response.data.token) { if (response.data && response.data.token) {
// 1. 토큰 저장 및 반응형 상태 동기화
localStorage.setItem('token', response.data.token); localStorage.setItem('token', response.data.token);
authToken.value = response.data.token; authToken.value = response.data.token;
// 2. 터미널에 성공 스크립트 출력
if (termInstance.value) { if (termInstance.value) {
termInstance.value.echo(`[[b;green;][SUCCESS]] ACCESS GRANTED. CREDENTIALS VERIFIED.`); termInstance.value.echo(`[[b;green;][SUCCESS]] ACCESS GRANTED. CREDENTIALS VERIFIED.`);
termInstance.value.echo(`[[b;green;][SYS]] WELCOME BACK, CENTRAL ADMIN AUTHORIZED.`);
} }
// 3. 폼 초기화 및 홈화면(유튜브)으로 화면 즉시 복귀
loginId.value = ''; loginId.value = '';
loginPw.value = ''; loginPw.value = '';
activeMenu.value = 'main'; activeMenu.value = 'main';
} }
} catch (error) { } catch (error) {
console.error("로그인 실패:", error); console.error("로그인 실패:", error);
// 실패 시 터미널 경고음 효과 및 붉은색 에러 로그 출력
if (termInstance.value) { if (termInstance.value) {
termInstance.value.echo(`[[b;red;][CRITICAL ERROR]] ACCESS DENIED! INVALID ACCESS KEY.`); termInstance.value.echo(`[[b;red;][CRITICAL ERROR]] ACCESS DENIED! INVALID ACCESS KEY.`);
termInstance.value.echo(`[[b;red;][WARN]] IP LOGGED. UNAUTHORIZED ATTEMPT REGISTERED.`); termInstance.value.echo(`[[b;red;][WARN]] IP LOGGED. UNAUTHORIZED ATTEMPT REGISTERED.`);
+1 -1
View File
@@ -13,7 +13,7 @@ export default defineConfig({
proxy: { proxy: {
// 로컬에서 /api로 요청을 보내면 백엔드 NAS 서버로 주소를 전달해 줍니다. // 로컬에서 /api로 요청을 보내면 백엔드 NAS 서버로 주소를 전달해 줍니다.
'/api': { '/api': {
target: 'http://192.168.0.215:18080', target: 'http://localhost:8080',
changeOrigin: true changeOrigin: true
} }
} }