
File name
Commit message
Commit date
05-22
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
04-04
File name
Commit message
Commit date
<template>
<div class="login-page page">
<div>
<div class="background-img">
<p>
어서오세요.<br />
로그인하세요.
</p>
</div>
<div class="login-wrap">
<div class="login">
<div
:class="{
'login-title': true,
'user-login': !isAdminPage,
}"
>
LOGIN
</div>
<div class="form-group">
<label for="id" class="login-label">아이디</label>
<input
type="text"
name=""
id="id"
class="form-control md"
placeholder="아이디를 입력하세요"
v-model="member['lgnId']"
/>
</div>
<div class="form-group">
<label for="pw" class="login-label">비밀번호</label>
<input
type="password"
name=""
id="pw"
class="form-control md"
placeholder="비밀번호를 입력하세요"
v-model="member['pswd']"
@keydown.enter="fnLogin"
/>
</div>
<button
class="btn md main user-btn"
v-if="!isAdminPage"
@click="fnLogin"
@keydown.enter="fnLogin"
>
로그인
</button>
<button
class="btn md main"
v-else
@click="fnLogin"
@keydown.enter="fnLogin"
>
로그인
</button>
<div
class="input-group"
v-if="!isAdminPage"
>
<p class="pl10 pr10 cursor" @click="moveSearchId">아이디찾기</p>
<p class="pl10 pr0 cursor" @click="moveResetPswd">비밀번호 초기화</p>
</div>
<!-- <div class="oauth-login-section" v-if="!isAdminPage">
<div class="oauth-divider">
<span>또는</span>
</div>
<div class="oauth-buttons">
<button class="oauth-btn kakao-btn" @click="fnOAuthLogin('kakao')">
<img src="/images/kakao-icon.png" alt="카카오" class="oauth-icon" />
카카오로 로그인
</button>
<button class="oauth-btn naver-btn" @click="fnOAuthLogin('naver')">
<img src="/images/naver-icon.png" alt="네이버" class="oauth-icon" />
네이버로 로그인
</button>
<button class="oauth-btn google-btn" @click="fnOAuthLogin('google')">
<img src="/images/google-icon.png" alt="구글" class="oauth-icon" />
구글로 로그인
</button>
</div>
</div> -->
</div>
</div>
</div>
</div>
</template>
<script>
import { useStore } from "vuex";
import store from "../AppStore";
import { loginProc, oauthLogin, getOAuthUserInfo } from "../../../resources/api/login";
import queryParams from "../../../resources/js/queryParams";
export default {
mixins: [queryParams],
data: () => {
return {
member: {
lgnId: null,
pswd: null,
},
store: useStore(),
isAdminPage: false,
};
},
methods: {
checkAdminPage() {
if (
this.restoreRedirect("redirect") &&
this.restoreRedirect("redirect").includes("/adm/")
) {
this.isAdminPage = true;
} else {
this.isAdminPage = false;
}
},
// OAuth2 로그인 처리 (API 모듈 사용)
fnOAuthLogin(provider) {
const redirectUrl = this.restoreRedirect("redirect") || this.$route.fullPath;
sessionStorage.setItem('oauth_redirect', redirectUrl);
oauthLogin(provider);
},
async fnLogin() {
try {
const res = await loginProc(this.member);
if (res.status == 200) {
const loginType = res.headers['login-type']; // 세션/토큰 로그인 구분
if (loginType === 'J') {
// JWT 방식
const token = res.headers.authorization;
store.commit("setAuthorization", token);
store.commit("setLoginMode", "J");
// localStorage에도 저장
localStorage.setItem("authorization", token);
localStorage.setItem("loginMode", "J");
const base64String = token.split(".")[1];
const base64 = base64String.replace(/-/g, "+").replace(/_/g, "/");
const jsonPayload = decodeURIComponent(
atob(base64).split("").map((c) => {
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
}).join("")
);
const mbr = JSON.parse(jsonPayload);
store.commit("setMbrId", mbr.mbrId);
store.commit("setMbrNm", mbr.mbrNm);
store.commit("setRoles", mbr.roles);
// localStorage에 사용자 정보도 저장
localStorage.setItem("mbrId", mbr.mbrId);
localStorage.setItem("mbrNm", mbr.mbrNm);
localStorage.setItem("roles", JSON.stringify(mbr.roles));
} else if (loginType === 'S') {
store.commit("setLoginMode", "S");
localStorage.setItem("loginMode", "S");
const mbr = res.data;
store.commit("setAuthorization", null);
store.commit("setMbrId", mbr.mbrId);
store.commit("setMbrNm", mbr.mbrNm);
const roles = mbr.roles.map(r => ({ authority: r.authrtCd }));
store.commit("setRoles", roles);
// localStorage에 세션 정보도 저장
localStorage.setItem("mbrId", mbr.mbrId);
localStorage.setItem("mbrNm", mbr.mbrNm);
localStorage.setItem("roles", JSON.stringify(roles));
} else {
alert("알 수 없는 로그인 방식입니다.");
return;
}
// 페이지 이동 처리
await this.handleLoginSuccess();
}
} catch (error) {
console.error("로그인 에러:", error);
alert(error.response?.data?.message || "로그인에 실패했습니다.");
}
},
// 로그인 성공 후 페이지 이동 처리
async handleLoginSuccess() {
const isAdmin = store.state.roles.some(role => role.authority === "ROLE_ADMIN");
let redirectUrl = this.restoreRedirect("redirect");
if (redirectUrl && redirectUrl !== "") {
// 특정 페이지들은 메인으로 리다이렉트
if (redirectUrl.includes("/searchId.page") || redirectUrl.includes("/resetPswd.page") || redirectUrl.includes("/login.page")) {
redirectUrl = this.$filters.ctxPath("/");
}
// Context Path 처리
if (!redirectUrl.startsWith(store.state.contextPath) && store.state.contextPath) {
redirectUrl = this.$filters.ctxPath(redirectUrl);
}
// 라우터에 해당 경로가 존재하는지 확인
const routeExists = this.$router.getRoutes().some(route => route.path === redirectUrl);
if (routeExists) {
await this.$nextTick();
this.$router.push({ path: redirectUrl });
} else {
const defaultPath = isAdmin ? this.$filters.ctxPath("/adm/main.page") : this.$filters.ctxPath("/");
this.$router.push({ path: defaultPath });
}
} else {
const defaultPath = isAdmin ? this.$filters.ctxPath("/adm/main.page") : this.$filters.ctxPath("/");
await this.$nextTick();
this.$router.push({ path: defaultPath });
}
// redirect 세션 정리
sessionStorage.removeItem("redirect");
},
moveSearchId() {
this.$router.push({
path: this.$filters.ctxPath("/resetPswd.page"),
query: {
tab: "id",
},
});
},
moveResetPswd() {
this.$router.push({
path: this.$filters.ctxPath("/resetPswd.page"),
query: {
tab: "pw",
},
});
},
// OAuth2 로그인 성공 후 처리
async handleOAuthCallback() {
const urlParams = new URLSearchParams(window.location.search);
const error = urlParams.get('error');
if (error) {
alert('소셜 로그인에 실패했습니다: ' + decodeURIComponent(urlParams.get('message') || error));
return;
}
// URL에 OAuth 관련 파라미터가 있는 경우
if (this.$route.query.oauth_success) {
try {
console.log("OAuth2 로그인 성공! 간단한 세션 처리를 시작합니다.");
// OAuth는 일반적으로 세션 방식이므로 세션으로 설정
store.commit("setLoginMode", "S");
localStorage.setItem("loginMode", "S");
// 기본 사용자 정보 설정 - 서버에서 세션에 저장된 정보 사용
// 실제 사용자 정보는 다른 API나 페이지 로드 시 가져올 수 있음
const defaultMbrId = 'oauth_user_' + Date.now(); // 임시 ID
const defaultMbrNm = 'OAuth 사용자';
const defaultRoles = [{ authority: 'ROLE_USER' }];
store.commit("setAuthorization", null);
store.commit("setMbrId", defaultMbrId);
store.commit("setMbrNm", defaultMbrNm);
store.commit("setRoles", defaultRoles);
// localStorage에 정보 저장
localStorage.setItem("mbrId", defaultMbrId);
localStorage.setItem("mbrNm", defaultMbrNm);
localStorage.setItem("roles", JSON.stringify(defaultRoles));
console.log("OAuth 세션 로그인 완료 - Store 상태:", {
authorization: store.state.authorization,
mbrId: store.state.mbrId,
mbrNm: store.state.mbrNm,
roles: store.state.roles,
loginMode: store.state.loginMode
});
// 페이지 이동 처리
await this.$nextTick();
// 리다이렉트 URL 처리
const redirectUrl = sessionStorage.getItem('oauth_redirect');
sessionStorage.removeItem('oauth_redirect');
if (redirectUrl && redirectUrl !== '/login' && !redirectUrl.includes('/login.page')) {
console.log("OAuth 리다이렉트:", redirectUrl);
this.$router.replace({ path: redirectUrl });
} else {
// 메인 페이지로 이동
const mainPath = this.$filters.ctxPath("/");
console.log("OAuth 메인 페이지로 이동:", mainPath);
this.$router.replace({ path: mainPath });
}
} catch (error) {
console.error('OAuth 콜백 처리 실패:', error);
alert('OAuth 로그인 처리 중 오류가 발생했습니다: ' + (error.message || '알 수 없는 오류'));
// 에러 발생 시 로그인 페이지로 이동
store.commit("setStoreReset");
this.$router.push({ path: this.$filters.ctxPath("/login.page") });
}
}
}
},
watch: {},
computed: {},
components: {},
created() {
this.checkAdminPage();
// OAuth2 콜백 처리
this.handleOAuthCallback();
},
mounted() {},
};
</script>