투케이2K

36. (NodeJs) [Mac Os] [JWT] : jsonwebtoken 모듈 사용해 Access Token 과 Refresh Token 갱신 수행 - token update 본문

NodeJs

36. (NodeJs) [Mac Os] [JWT] : jsonwebtoken 모듈 사용해 Access Token 과 Refresh Token 갱신 수행 - token update

투케이2K 2024. 1. 4. 20:45
반응형

[개발 환경 설정]

개발 툴 : VS CODE

개발 언어 :NodeJs

 

[로직 설명]

1. 사용자가 로그인 수행 실시

2. 서버에서 사용자 확인 후, Access Token 과 Refresh Token 을 생성하여 클라이언트에게 반환

3. 클라이언트는 두 토큰을 저장 수행

4. 클라이언트가 권한 인증이 필요한 요청을 할 때마다 Access Token 을 헤더에 실어서 요청 수행

5. 서버는 헤더의 Access Token 토큰을 검증하고, 토큰이 만료되었다면 서버는 클라이언트에게 만료되었다는 응답을 리턴

6. 클라이언트는 만료 된 토큰을 재발급 받기위해, 만료 된 Access Token 과 Refresh Token 을 헤더에 실어 서버에게 새로운 토큰 발급을 요청 수행

7. 서버는 Access Token 과 Refresh Token 을 모두 검증 한 후, Refresh Token 이 만료되지 않았다면 새로운 Access Token 을 발급하여 클라이언트에게 반환 수행
    Refresh Token 이 만료된 경우는 Refresh Token 도 새롭게 발급하여 Access Token 과 Refresh Token 을 반환 수행

8. 클라이언트는 전달 받은 두 토큰을 저장 후 필요한 요청을 할 때마다 Access Token 을 헤더에 실어서 요청 수행

[사전 설정]

 

[app.js : 소스 코드]

// ----------------------------------------------------------------------------------------------

const express = require('express')
const app = express()

// ---------------------------------------

app.set('view engine', 'ejs') // [Page] : [Render]
app.set('views', './views') // [Page] : [Render]

// ---------------------------------------

//app.use(express.urlencoded({ extended: true })) // [Http] : [URL] : [Encode]

// ---------------------------------------

app.use(express.json()) // [Http] : [Body] : [Json]

// ---------------------------------------

const jwt = require('jsonwebtoken'); // [jwt 모듈]

// ----------------------------------------------------------------------------------------------

// [Get] : Path = [/refreshToken] : http://localhost:3000/refreshToken
app.post('/refreshToken', function (req, res) {
    console.log("")
    console.log("==============================================================================")
    console.log("[Server] :: [Get] :: [Path = /refreshToken] :: [Start]")
    console.log("--------------------------------------------------------------------------")
    console.log("[INPUT] :: [Headers] :: " + JSON.stringify(req.headers))
    console.log("--------------------------------------------------------------------------")
    console.log("[INPUT] :: [Cookies] :: " + JSON.stringify(req.cookies))
    console.log("--------------------------------------------------------------------------")
    console.log("[INPUT] :: [Params] :: " + JSON.stringify(req.query))
    console.log("--------------------------------------------------------------------------")
    console.log("[INPUT] :: [Body] :: " + JSON.stringify(req.body))
    console.log("==============================================================================")
    console.log("")

    // [body 값 체크]
    let id = req.body.id; // 사용자 아이디
    let pw = req.body.pw; // 사용자 비밀번호

    let auth = req.body.auth; // 인증 토큰
    let refresh = req.body.refresh; // 갱신 토큰

    if (id != undefined && id != "" && pw != undefined && pw != "" 
        && auth != undefined && auth != "" && refresh != undefined && refresh != ""){

        // [1] : [Refresh Token] : [검증 수행]
        try {

            let payload = jwt.verify(refresh, "jwt_secret"); // [Refresh Token]

            console.log("")
            console.log("==============================================================================")
            console.log("[Server] :: [Get] :: [Path = /refreshToken] :: [payload]")
            console.log("--------------------------------------------------------------------------")
            console.log(payload)
            console.log("==============================================================================")
            console.log("")

            // [2] : [Refresh Token] : [정상] >> [Access Token] 발급
            let auth_token = jwt.sign(
                { id: id, pw: pw }, // 암호화에 사용 될 정보
                "jwt_secret", // 암호화에 사용될 key
                {expiresIn: "60s"} // [테스트] 토큰 만료 60 초 / 실제 1h (1 시간)
            );

            // [리턴 반환]
            res.status(200).json({ "result" : { "auth" : auth_token, "refresh" : refresh} });  

        } catch (err) {
            console.log("")
            console.log("==============================================================================")
            console.log("[Server] :: [Get] :: [Path = /refreshToken] :: [token] :: [Error]")
            console.log("--------------------------------------------------------------------------")
            console.log(err)
            console.log("==============================================================================")
            console.log("")

            // [3] : [Refresh Token] : [비정상] >> [Refresh Token] 및 [Access Token] 발급
            let auth_token = jwt.sign(
                { id: id, pw: pw }, // 암호화에 사용 될 정보
                "jwt_secret", // 암호화에 사용될 key
                {expiresIn: "60s"} // [테스트] 토큰 만료 60 초 / 실제 1h (1 시간)
            );

            let refresh_token = jwt.sign(
                {}, 
                "jwt_secret", // 암호화에 사용될 key
                {expiresIn: "120s"} // [테스트] 토큰 만료 120 초 / [실제] 14d (14 일)
            ); 
            
            // [토큰이 없거나 만료기간이 지난 경우] : [두 토큰 새롭게 반환]
            res.status(200).json({ "result" : { "auth" : auth_token, "refresh" : refresh_token} });
        } 
    }
    else {
        res.status(403).json({ "result" : "error" });
    }

})

// ----------------------------------------------------------------------------------------------

// [Server] : [Start]
//*
app.listen(3000, function () {
    console.log("")
    console.log("==============================================================================")
    console.log("[Server] :: [Port = 3000] :: [Start]")
    console.log("==============================================================================")
    console.log("")
})
// */
 

[결과 출력]

 

 

반응형
Comments