바닐라js 를 사용한 jwt token 로그인 구현

안녕하세요!
오늘은 지난 글(https://velog.io/@bm_rabbit96/Spring-Interceptor-%EC%99%80-JWT-Token-%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%9D%B4%EB%8F%99-%EB%AC%B8%EC%A0%9C) 이후 개선한 내용을 가지고 글을 써보려고 합니다.

결론부터 말하면 지난번처럼 로그인 처리를 하면 절대 안될 것 같습니다.

그 이유는 동적 form을 생성한다는 것 자체가 좋은 방법이 아니라고 하시더라구요. 그럴거면 차라리 form 안에 input 을 하나 만들어서 value 값만 넣어주는 방식이 더 좋다고 합니다.

그래서 여러 고민 끝에 택한 방식은 생각 자체를 뒤집었습니다.
기존과 같은 문제점이 자꾸 생겼던 이유는 이동하려는 페이지를 사전에 로딩하지 못하게 하려고 했기 때문입니다.

간단히 말해서 A페이지에 접속하려고 할때, 로그인이 되어 있는 상태가 아니라면 아에 A 페이지를 로딩조차 못하게 사전에 처리하려고 했었습니다.

그러나 이렇게 하니 인터셉터와 화면전환시 데이터를 포함해서 보내는 기능 사이에서 문제점이 발생했습니다.
이를 해결하기 위해 A 페이지를 로딩을 먼저 한 다음 로딩시 디폴트로 실행되는 자바스크립트 파일에서 tokensesseionStorage에 있다면 그냥 ok, 없다면 로그인이 되지 않은 상태에서 접근하려고 했다는 뜻이므로 그땐 location.href = location.origin+'/login' 이렇게 로그인 페이지로 이동하게끔 하면 됩니다.

아마 vue.jsreact를 사용하면 라우터를 사용한다던데 이런 부분은 더 공부를 해야할 것 같네요.

const needAuth = () => {
    const auth = sessionStorage.getItem("Authorization");
    if(auth==null){
        location.href = location.origin + `/login`;
    }
}

needAuth 함수를 권한이 필요한 페이지에 import 해주었습니다.

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <th:block th:replace="fragments/header.html :: header-fragment"></th:block>
    <link rel="stylesheet" href="/css/index.css">
</head>
<body>
<div class="container h-100">
    <div class="row align-items-center h-100">
        <div class="jumbotron align-self-center">
            <h1 class="text-center"><b>작전명 <span class="highlight">투게더</span>!</b></h1>
            <p class="text-center">친구들과 함께 당신의 작전을 만들어보세요.</p>
            <div class="contentContainer" id="logoutState">
                <p class="text-center"><a href="/login" class="btn btn-primary btn-lg">로그인</a></p>
                <p class="text-center"><a href="/signUp" class="btn btn-primary btn-lg">회원가입</a></p>
            </div>
            <div class="contentContainer" id="loginState" style="display: none">
                <div id="btn-create" class="mb-3 text-center">
                    <button type="submit" id="create-button" class="btn btn-primary">작전 만들기</button>
                </div>
                <div id="btn-logout" class="mb-3 text-center">
                    <button type="submit" id="logout-button" class="btn btn-primary">로그아웃</button>
                </div>
            </div>
        </div>
    </div>
</div>
<th:block th:replace="fragments/footer.html :: footer-fragment"></th:block>
<script src="/js/index.js"></script>
</body>
</html>

홈 화면입니다. 로그인 여부에 따라 UI 상에서 보여주는 부분을 달리 해주었습니다.

const isLoginCheck = () => {
    const logoutState = document.getElementById("logoutState");
    const loginState = document.getElementById("loginState");

    const token = sessionStorage.getItem("Authorization");
    if(token!==null){
        logoutState.style.display="none";
        loginState.style.display="block";
    }
}

로그인시 session을 체크하고 보여주는 부분을 처리해주었습니다.

감사합니다!

좋은 웹페이지 즐겨찾기