Programing

jwt - Vue.js에 토큰을 저장할 위치

c10106 2022. 3. 17. 21:04
반응형

jwt - Vue.js에 토큰을 저장할 위치

일부 보안 블로그에서 토큰을 로컬 저장소에 저장하는 것은 안전하지 않기 때문에 원하는 것은 토큰을 vuex 저장소에 저장하는 것이며, 모든 api 호출은 다음 요청에 해당 토큰을 포함할 것이다.

하지만 로그인 성공 시 애초에 토큰에 접근할 수 없고, 토큰을 vuex 스토리지에 처음 저장하고자 하는데, 토큰을 응답 본문에 보낼까 생각했지만 취약한 방법이 될 것 같아 헤더로 전송["승인"]한다.

아래는 내 user.js와 로그인이다.각각 vue 파일.

router.post('/login', function (req, res, next) {
    const {
        UserName,
        Password
    } = req.body;

    if (UserName.length == 0 || Password.length == 0) {
        res.status(400).json({
            message: 'Email or Password is empty',
        });
    } else {
        login_pool.query(
            'SELECT * FROM authentication WHERE user_name = ($1) and password = crypt(($2), password)',
            [UserName, Password],
            (err, results) => {
                if (err) {
                    throw err;
                } else if (results.rows.length == 1) {
                    // On Successful Login
                    const token = jwt.sign(
                        {
                            user_name: results.rows[0].user_name,
                            full_name: results.rows[0].full_name,
                            phone_number: results.rows[0].phone_number,
                        },
                        btoa(process.env.TOKEN_SECRET), // converting token_secret to base 64
                        { expiresIn: '1800s' },
                        { algorithm: 'HS256' },
                        (err) => {
                            if (err) {
                                res.status(400).json({
                                    message: 'Not able to create a token',
                                });
                                console.log(err);
                            }
                        }
                    );
                    res.header('Authorization', `Bearer ${token}`);
                    res.status(201).json({
                        message: results.rows[0].full_name + 'logged in.',
                    });
                    console.log(results.rows[0].full_name + 'Just Logged In. ');
                } else {
                    login_pool.query(
                        'SELECT * FROM authentication WHERE user_name = ($1)',
                        [UserName],
                        (errUser, resultUser) => {
                            if (resultUser.rows.length != 1) {
                                res.status(400).json({
                                    message: 'User with this email does not exist',
                                });
                            } else {
                                res.status(400).json({
                                    message: 'Password is not correct',
                                });
                            }
                        }
                    );
                }
            }
        );
    }
});
LoginSubmit() {
    this.axios
        .post(
            "http://127.0.0.1:3000/users/login",
            {
                UserName: this.UserName,
                Password: this.Password,
            },
            {
                headers: {
                    "Content-Type": "application/json;charset=UTF-8",
                    "Access-Control-Allow-Origin": "*",
                    Accept: "application/vnd.api+json",
                },
            }
        )
        .then(
            (res) => {
                // successful login
                console.log(res.headers); // authentication header not present here
                this.Error = "";
                console.log(this.axios.defaults.headers.common); // authentication header not present here
            },
            (err) => {
                console.log(err.response.data.message);
                this.Error = err.response.data.message.replace(/"/g, "");
            }
        );
},

이렇게 하는 것을 본 적이 없다.JWT는 일부 응답자의 신체 일부로서 전송될 수 있다.POST /auth끝점그런 다음 어떤 종류의 스토리지를 사용하여 토큰을 저장하십시오.

그것이 localStorage인지 아니면 쿠키인지 논쟁의 여지가 있다. 나는 개인적으로 localStorage를 사용하여 API가 가능한 상태 비저장일 수 있다.그러나 쿠키를 사용할 때는 쿠키의 어떤 종류의 만료를 설정하여 만료일 이후 삭제되도록 할 수 있다.

Vuex 스토어는 본질적으로 브라우저 창을 새로 고치면 모든 콘텐츠가 손실되는 글로벌 상태 객체다.Vuex 저장소에 로드/저장하는 localStorage/sessionStorage와 연결하지 않는 경우.

그래서 나는 네가 그 일을 없앨 것을 제안한다.Access-Control-Expose-Headers: Authorization헤더로 JWT 토큰을 인증하는 동안 POST 본문 응답으로 보내십시오.인증 요청의 안전성은 사용 여부에 따라 다름http또는https항상 사용하길 원하시죠?https왜냐하면, 그렇지 않은 모든 것은 어떤 악의적인 네트워크 소유자에 의해 쉽게 일반 텍스트로 읽힐 수 있기 때문이다.

res.header({
   Authorization: "Bearer" + token,
   "Access-Control-Expose-Headers": "Authorization",
});

이제 Access-Control-Expose-Headers를 사용하여 문제를 해결한 후 프런트엔드 부분의 권한 부여 헤더에 액세스할 수 있음res.headers["authorization"]

우리의 vue 앱은 토큰을 sessionStorage에 저장하고 있고 그것 때문에 이상한 문제에 부딪히고 있다.

우리가 보고 기대하는 정상적인 행동은 사용자가 새로운 탭으로 우리의 앱에 갈 때마다 그들은 인증을 해야 한다.이것은 모든 브라우저에서 항상 잘 작동한다.윈도 크롬에서만 사용자가 인증할 필요가 없는 경로가 하나 있다.

  1. 웹 사이트를 로드했는지 여부는 관련이 없으며 하나 이상의 다른 탭 또는 Chrome 인스턴스가 열려 있는지 확인하십시오.
  2. 당사 사이트에 로그인
  3. 탭을 닫으십시오.
  4. 새 탭 또는 새 크롬 인스턴스를 여십시오.
  5. 브라우저 기록으로 이동하여 방금 닫힌 탭을 복원하십시오.

이 시나리오에서는 sessionStorage가 복원되고 사용자가 로그인된다.나는 이것을 간단한 HTML 페이지에서 복제할 수 있었다.

세션스토리지 외에 JWT 토큰을 저장할 수 있는 다른 방법이 있는가?

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Session Persists Test</title>
    <style>
        div { margin: .75em; }
        input { margin-left: 2em;}
    </style>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    <script>
        $(document).ready(function () {
            const formatDateTime = function (date_ob) {
                let date = ("0" + date_ob.getDate()).slice(-2);
                let month = ("0" + (date_ob.getMonth() + 1)).slice(-2);
                let year = date_ob.getFullYear();
                let hours = ("0" + date_ob.getHours()).slice(-2);
                let minutes = ("0" + date_ob.getMinutes()).slice(-2);
                let seconds = ("0" + date_ob.getSeconds()).slice(-2);
                return `${month}-${date}-${year} ${hours}:${minutes}:${seconds}`;
            };

            const updateTimes = () => {
                let now_token = formatDateTime(new Date());
                let session_now_token = sessionStorage.getItem('now_token');

                if (session_now_token == null) {
                    session_now_token = now_token;
                    sessionStorage.setItem('now_token', session_now_token);
                }
                $("#sessionTime").text(`Session Time: ${session_now_token}`);
                $("#lastCall").text(`Current Time: ${now_token}`);
            }

            $("#updateSession").click(function () {
                sessionStorage.clear();
                location.reload();
            });

            $('#updateTime').click(updateTimes);

            updateTimes();
        });
    </script>
</head>
<body>
<h1>Session Persists Test</h1>
<div><span id="sessionTime">Session Time: (please enable Javascript not running>)</span><input id="updateSession" type="button" value="Update Session Time"></div>
<div><span id="lastCall">Current Time: (please enable Javascript not running>)</span><input id="updateTime" type="button" value="Update Current Time (or press F5)"></div>
<H3>Testing of how long a browser session persists.</H3>
<div>
    <p>Google Chrome Version 97.0.4692.99 on Windows is not clearing the session when restoring a tab from the history. This site
        has been created to test and demo that issue.</p>
    <ul>
        <li>When this page is first loaded (or the Update Session time button is pressed) the session variable with the
            time is updated from the server.
        </li>
        <li>Each time the browser is refreshed (F5) the current time is updated.</li>
        <li>When a new tab opened to this site, the there will be a new session storage and a new session time.</li>
    </ul>
    <h3>The Problem:</h3>
    <p>A new session is NOT create when restoring a tab from history.  To reproduce, using Google Chrome on Windows do the following:</p>
    <ol>
        <li>Make sure there is at least one other tab or instance of Chrome open, whether or not there is a website
            loaded is not relevant.
        </li>
        <li>Load this site and record the session time.</li>
        <li>Close the tab that is displaying this site.</li>
        <li>Open either a new tab or new instance of Chrome.</li>
        <li>Go to the browser History and restore the tab that was just closed.</li>
    </ol>
    <p>The session time is the same time recorded in step 2. As long as there is at least one instance of Chrome
        running, when restoring from history, the session will also be restored.</p>
    <p>This is not the way eitehr Edge or Firefox is currently working. Both created a new session. Which browser is
        working correctly?</p>
</div>
</body>
</html>

참조URL: https://stackoverflow.com/questions/67554333/jwt-where-to-store-token-in-vue-js

반응형