IT

로그아웃 시 JWT 토큰을 폐기하는 방법은 무엇입니까?

itgroup 2023. 9. 5. 20:08
반응형

로그아웃 시 JWT 토큰을 폐기하는 방법은 무엇입니까?

저는 jwt 플러그인과 hapijs 전략을 사용하고 있습니다.

나는 사용자 로그인 중 jwt 토큰을 생성할 수 있으며, 'jwt' 전략을 통해 동일한 토큰을 사용하여 다른 API를 인증할 수 있습니다.

을 토을설정다니에 .request.state.USER_SESSION의 경우에는USER_SESSION토큰 이름입니다.또한 이 토큰을 데이터베이스에 저장하지 않습니다.

그런데 로그아웃 시 jwt 토큰을 어떻게 폐기합니까?

방법을 제안해 주세요.

JWT는 브라우저에 저장되므로 클라이언트 측에서 쿠키를 삭제하는 토큰을 제거합니다.

계정 삭제/차단/일시 중단, 암호 변경, 권한 변경, 관리자 로그아웃 등과 같이 만료 시간 전에 서버 측에서 토큰을 무효화해야 하는 경우 블랙리스트 만들기 또는 토큰 회전과 같은 일반적인 기술에 대한 JSON토큰 무효화를 살펴보십시오.

토큰을 만든 후에는 수동으로 만료할 수 없습니다.따라서 세션에서와 같이 서버 측에서 JWT로 로그아웃할 수 없습니다.

JWT는 상태 비저장입니다. 즉, 필요한 모든 것을 페이로드에 저장하고 모든 요청에 대해 DB 쿼리를 수행하지 않아야 합니다.그러나 엄격한 로그아웃 기능을 사용하려는 경우 클라이언트 측에서 토큰을 정리했음에도 토큰 자동 만료를 기다릴 수 없으므로 상태 비저장 논리를 무시하고 일부 쿼리를 수행해야 할 수 있습니다.그래서 해결책은 무엇입니까?

  • 토큰에 대한 적절한 만료 시간 설정

  • 로그아웃 시 클라이언트 측에서 저장된 토큰 삭제

  • 승인된 모든 요청에 대해 블랙리스트에 대해 제공된 토큰 쿼리

블랙리스트

더 이상 유효하지 않고 아직 만료되지 않은 모든 토큰의 "블랙리스트"입니다.토큰이 만료될 때까지 남은 시간으로 설정되는 TTL 선택사항이 있는 DB를 문서에 사용할 수 있습니다.

레디스

Redis는 블랙리스트에 적합한 옵션으로, 메모리 내에서 목록에 빠르게 액세스할 수 있습니다.그런 다음 승인된 모든 요청에서 실행되는 어떤 종류의 미들웨어에서 제공된 토큰이 블랙리스트에 있는지 확인해야 합니다.그렇다면 무단 오류를 발생시켜야 합니다.그렇지 않은 경우에는 그대로 두면 JWT 검증에서 처리하고 만료되었거나 아직 활성 상태인지 여부를 식별합니다.

자세한 내용은 Arpy Vanyan의 JWT. 사용 시 로그아웃하는 방법(신용 및 참조)을 참조하십시오.

클라이언트 측에서 로그아웃할 때 가장 쉬운 방법은 브라우저 저장소에서 토큰을 제거하는 것입니다.

하지만 노드 서버에서 토큰을 파괴하려면 어떻게 해야 하나요?

JWT 패키지의 문제는 토큰을 파괴하는 방법이나 방법을 제공하지 않는다는 것입니다.

따라서 서버 측 토큰을 파괴하기 위해 JWT 대신 jwt-redis 패키지를 사용할 수 있습니다.

이 라이브러리(jwt-redis)는 jsonwebtoken 라이브러리의 전체 기능을 하나의 중요한 추가 기능으로 완전히 반복합니다.Jwt-redis를 사용하면 토큰 레이블을 redis에 저장하여 유효성을 확인할 수 있습니다.redis에 토큰 레이블이 없으면 토큰이 유효하지 않습니다.jwt-redis에서 토큰을 파괴하려면 파괴 방법이 있습니다.

다음과 같은 방식으로 작동합니다.

npm에서 jwt-redis 설치

작성 방법 -

var redis = require('redis');
var JWTR =  require('jwt-redis').default;
var redisClient = redis.createClient();
var jwtr = new JWTR(redisClient);

jwtr.sign(payload, secret)
    .then((token)=>{
            // your code
    })
    .catch((error)=>{
            // error handling
    });

확인하기 -

jwtr.verify(token, secret);

파괴하기 -

jwtr.destroy(token)

참고: 만료를 제공할 수 있습니다.JWT에서 제공하는 것과 동일한 토큰 로그인 중 인.

토큰을 제거하려면 프런트 엔드 응용 프로그램에서 쉽게 제거할 수 있습니다. 토큰을 저장하는 쿠키를 지우는 경우

반면에 토큰을 무효화하려는 경우 몇 가지 방법이 있습니다. 아래는 몇 가지 방법입니다.

생성된 모든 토큰이 백엔드에 저장된 경우, 해당 스토리지를 지우는 것은 간단합니다. 토큰이 사용자에게 매핑된 경우 특정 사용자에 대한 토큰을 지우는 것만 하면 됩니다.

"invalidate_before"와 같은 날짜 필드를 사용자와 함께 추가할 수 있습니다. 이 필드는 암호 변경, 모든 장치에서 로그아웃 등이 발생할 때 업데이트해야 합니다.이러한 이벤트에 대해 invalidate_before를 currentTime()으로 업데이트하기만 하면 됩니다.새 토큰이 생성될 때마다 토큰 페이로드에 생성된 시간을 추가합니다. 수신 요청 시 토큰의 유효성을 검사하려면 payload에 생성된 시간이 db에 있는 해당 사용자에 대한 invalid_before time보다 큰지 확인하십시오.

새 사용자를 생성할 때 해당 사용자만을 위한 암호를 생성한 다음, 특정 암호로 모든 사용자 토큰에 서명할 수 있습니다. (2) 암호 변경, 모든 장치에서 로그아웃 등의 이벤트와 마찬가지로 새 암호를 생성해야 합니다.이렇게 하면 토큰 서명을 확인하여 무효화할 수도 있습니다.

(2)(3)의 오버헤드는, 검증은 2단계 프로세스가 될 것이며, DB 판독을 포함합니다.

편집: (3)의 경우 소금을 대신 사용할 수 있습니다(최종 비밀은 공통 비밀 + 특정 사용자에 대한 소금). 따라서 소금을 변경하여 단일 사용자의 토큰을 무효화하거나 공통 비밀을 변경하여 모든 사용자의 토큰을 무효화할 수 있습니다.

토큰에 "발행 시간"을 추가하고 서버의 각 사용자에 대해 "마지막 로그아웃 시간"을 유지할 수 있습니다.토큰 유효성을 확인할 때는 "마지막 로그아웃 시간" 이후의 "발행 시간"도 확인하십시오.

다른 답변은 다양한 설정에 대한 자세한 솔루션을 제공하지만 일반적인 답변을 찾는 사용자에게는 도움이 될 수 있습니다.

세 가지 일반 옵션이 있습니다. 하나 이상을 선택하십시오.

  1. 클라이언트 측에서는 Javascript를 사용하여 브라우저에서 쿠키를 삭제합니다.

  2. 서버 측에서 쿠키 값을 빈 문자열 또는 쓸모없는 문자열로 설정합니다(예:"deleted") 및 쿠키 만료 시간을 과거 시간으로 설정합니다.

  3. 서버에서 데이터베이스에 저장된 새로 고침 토큰을 업데이트합니다.이 옵션을 사용하여 로그인한 모든 장치에서 사용자를 로그아웃합니다(새로 고침 토큰이 유효하지 않게 되고 다시 로그인해야 함).

passportJsjwt 전략을 사용하는 경우 토큰을 변경하여 무효화할 수 있습니다.secretOrKey모든 사용자의 토큰이 무효화됩니다.

사용 중인 인증 라이브러리에 유사한 속성이 있을 것입니다.

알겠습니다. 그래서 공유하고 싶은 것을 시도해 보았습니다. 저는 그것이 정말 쉽고 효과적인 방법이라고 생각합니다. 그래서 기본적으로 토큰이나 블랙리스트를 파괴하는 대신에 우리는 그것의 중간에 임의의 값을 임의의 인덱스나 심지어 임의의 숫자(또는 임의의 해시된 숫자)처럼 추가하면 누구나 그것을 뒤집고 관찰하기 어렵게 만들 수 있습니다.이전에 유효했던 토큰을 확보합니다. 이렇게 하면 이 토큰이 비활성화되어 사용자가 아무 곳에도 갈 수 없게 됩니다. 프런트엔드에서 사용자를 다시 로그인하도록 리디렉션할 수 있습니다. (또는 백엔드에서 다시 로그인할 수도 있습니다. 프론트엔드에서 로그인하는 경우에도 로그인 페이지로 리디렉션됩니다. 모두 정상입니다. 여기 내 코드가 있습니다.우선 토큰(암호 및 사용자 이름)이 괜찮다면 토큰을 req.token에 추가하여 내가 이 미들웨어를 호출할 때마다 사용자의 토큰이 req.token에 저장되도록 하는 인증 미들웨어를 가지고 있습니다.

router.post('/logout', auth, async(req, res) => {
    try{
        let randomNumberToAppend = toString(Math.floor((Math.random() * 1000) + 1));
        let randomIndex = Math.floor((Math.random() * 10) + 1);
        let hashedRandomNumberToAppend = await bcrypt.hash(randomNumberToAppend, 10);
    
        // now just concat the hashed random number to the end of the token
        req.token = req.token + hashedRandomNumberToAppend;
        return res.status(200).json('logout');
    }catch(err){
        return res.status(500).json(err.message);
    }
});

지금은 해시된 임의의 숫자를 토큰 끝에 연결합니다. 즉, 더 이상 유효하지 않으므로 사용자는 로그인 페이지로 리디렉션되므로 다시 로그인해야 합니다.

언급URL : https://stackoverflow.com/questions/37959945/how-to-destroy-jwt-tokens-on-logout

반응형