[node.js] JWT (JSON Web Token) 자동 만료 연장

새로운 REST API에 JWT 기반 인증을 구현하고 싶습니다. 그러나 토큰에 만료가 설정되었으므로 자동으로 연장 할 수 있습니까? 해당 기간 동안 응용 프로그램을 적극적으로 사용하는 경우 X 분마다 로그인하지 않아도됩니다. 그것은 엄청난 UX 실패 일 것입니다.

그러나 만기를 연장하는 것은 새로운 토큰을 생성 (그리고이 만료 될 때까지 이전은 여전히 ​​유효). 그리고 각 요청 후에 새 토큰을 생성하는 것은 어리석은 소리입니다. 둘 이상의 토큰이 동시에 유효한 경우 보안 문제처럼 들립니다. 물론 블랙리스트를 사용하여 이전에 사용한 것을 무효화 할 수는 있지만 토큰을 저장해야합니다. JWT의 장점 중 하나는 스토리지가 없다는 것입니다.

Auth0이 어떻게 해결했는지 알았습니다. 그들은 JWT 토큰뿐만 아니라 새로 고침 토큰도 사용합니다 :
https://docs.auth0.com/refresh-token

그러나 다시 (Auth0없이) 이것을 구현하려면 새로 고침 토큰을 저장하고 만료를 유지해야합니다. 그렇다면 진정한 이점은 무엇입니까? JWT가 아닌 하나의 토큰 만 가지고 서버에서 만료를 유지하는 이유는 무엇입니까?

다른 옵션이 있습니까? JWT를 사용하는 것이이 시나리오에 적합하지 않습니까?



답변

Auth0에서 일하고 새로 고침 토큰 기능 디자인에 참여했습니다.

그것은 모든 응용 프로그램의 유형에 따라 달라지며 여기에 우리의 권장되는 방법입니다.

웹 애플리케이션

좋은 패턴은 토큰이 만료되기 전에 새로 고치는 것입니다.

토큰 만료를 일주일로 설정하고 사용자가 웹 응용 프로그램을 열 때마다 그리고 1 시간마다 토큰을 새로 고칩니다. 사용자가 일주일 이상 응용 프로그램을 열지 않으면 다시 로그인해야하며 이는 허용되는 웹 응용 프로그램 UX입니다.

토큰을 새로 고치려면 API에 만료되지 않은 유효한 JWT를 수신하고 새 만료 필드와 동일한 서명 된 JWT를 리턴하는 새 엔드 포인트가 필요합니다. 그런 다음 웹 응용 프로그램은 토큰을 어딘가에 저장합니다.

모바일 / 네이티브 애플리케이션

대부분의 기본 응용 프로그램은 한 번만 로그인합니다.

아이디어는 새로 고침 토큰이 만료되지 않으며 항상 유효한 JWT로 교환 될 수 있다는 것입니다.

절대로 만료되지 않는 토큰의 문제는 결코 의미하지 않습니다. 휴대 전화를 분실하면 어떻게합니까? 따라서 사용자가 어떻게 든 식별 할 수 있어야하며 응용 프로그램은 액세스를 취소하는 방법을 제공해야합니다. “maryo ‘s iPad”와 같은 장치 이름을 사용하기로 결정했습니다. 그런 다음 사용자는 응용 프로그램으로 이동하여 “maryo ‘s iPad”에 대한 액세스를 취소 할 수 있습니다.

또 다른 방법은 특정 이벤트에서 새로 고침 토큰을 취소하는 것입니다. 흥미로운 이벤트는 비밀번호를 변경하는 것입니다.

우리는 JWT가 이러한 사용 사례에 유용하지 않다고 생각하므로 무작위로 생성 된 문자열을 사용하여 측면에 저장합니다.


답변

인증을 직접 처리하는 경우 (즉, Auth0와 같은 공급자를 사용하지 않는 경우) 다음이 작동 할 수 있습니다.

  1. 비교적 짧은 만기와 토큰을 발행 JWT는 15 분을 말한다.
  2. 응용 프로그램은 토큰이 필요한 거래 전에 토큰 만료 날짜를 확인합니다 (토큰에 만료 날짜가 포함됨). 토큰이 만료되면 먼저 API에 토큰을 ‘새로 고침’하도록 요청합니다 (UX에 투명하게 수행됨).
  3. API는 토큰 새로 고침 요청을 가져 오지만 먼저 사용자 데이터베이스에 대해 ‘재승 인’플래그가 설정되어 있는지 확인합니다 (토큰에 사용자 ID를 포함 할 수 있음). 플래그가 있으면 토큰 새로 고침이 거부되고 그렇지 않으면 새 토큰이 발행됩니다.
  4. 반복.

데이터베이스 백엔드의 ‘reauth’플래그는 예를 들어 사용자가 비밀번호를 재설정 한 경우 설정됩니다. 사용자가 다음에 로그인하면 플래그가 제거됩니다.

또한 사용자가 적어도 72 시간마다 한 번 로그인해야하는 정책이 있다고 가정하겠습니다. 이 경우 API 토큰 새로 고침 논리는 사용자 데이터베이스에서 사용자의 마지막 로그인 날짜를 확인하고 해당 기준에 따라 토큰 새로 고침을 거부 / 허용합니다.


답변

백엔드에서 RESTful API를 사용하여 응용 프로그램을 HTML5로 옮길 때 고민 중이었습니다. 내가 생각해 낸 해결책은 다음과 같습니다.

  1. 로그인에 성공하면 세션 시간이 30 분 (또는 일반적인 서버 측 세션 시간) 인 토큰이 클라이언트에 발행됩니다.
  2. 클라이언트 측 타이머는 만료 시간 전에 토큰을 갱신하기 위해 서비스를 호출하기 위해 만들어집니다. 새로운 토큰은 향후 통화에서 기존 토큰을 대체합니다.

보다시피, 이렇게하면 자주 새로 고침 토큰 요청이 줄어 듭니다. 토큰 갱신 호출이 트리거되기 전에 사용자가 브라우저 / 앱을 닫으면 이전 토큰이 시간이 지나면 다시 로그인해야합니다.

사용자의 비 활동을 수용하기 위해보다 복잡한 전략을 구현할 수 있습니다 (예 : 열린 브라우저 탭 무시). 이 경우 갱신 토큰 호출에는 정의 된 세션 시간을 초과하지 않아야하는 예상 만료 시간이 포함되어야합니다. 응용 프로그램은 이에 따라 마지막 사용자 상호 작용을 추적해야합니다.

긴 만료를 설정하는 아이디어가 마음에 들지 않으므로이 방법은 덜 빈번한 인증이 필요한 기본 응용 프로그램에서는 제대로 작동하지 않을 수 있습니다.


답변

백엔드에 추가 보안 스토리지없이 JWT를 무효화하는 대체 솔루션 jwt_version은 users 테이블에 새 정수 열 을 구현하는 것 입니다. 사용자가 기존 토큰을 로그 아웃하거나 만료하려는 경우 단순히 jwt_version필드 를 증가시킵니다 .

새 JWT를 생성 할 때 jwt_version새 JWT가 다른 모든 JWT를 대체해야하는 경우 사전에 값을 증분하여 선택적으로 JWT 페이로드로 인코딩하십시오 .

JWT의 유효성을 검증 할 때 jwt_version필드가 함께 비교 user_id되고 일치하는 경우에만 권한이 부여됩니다.


답변

좋은 질문이며 질문 자체에 풍부한 정보가 있습니다.

이 문서 새로 고침 토큰 : 사용시기와 JWT를 가진 그들은 상호 작용하는 방법 이 시나리오에 대한 좋은 아이디어를 제공합니다. 일부 요점은 다음과 같습니다.

  • 새로 고침 토큰에는 새 액세스 토큰을 얻는 데 필요한 정보가 들어 있습니다.
  • 새로 고침 토큰도 만료 될 수 있지만 오래 지속됩니다.
  • 새로 고침 토큰은 일반적으로 누출되지 않도록 엄격한 저장소 요구 사항이 적용됩니다.
  • 권한 서버에서 블랙리스트에 올릴 수도 있습니다.

또한 한 번 봐 걸릴 auth0 / 각도-JWT AngularJS와를

웹 API의 경우. ASP .NET Web API 2 및 Owin을 사용하여 AngularJS 앱에서 OAuth 새로 고침 토큰 사용을 읽으십시오.


답변

실제로 PHP에서 Guzzle 클라이언트를 사용하여 API의 클라이언트 라이브러리를 만들 때 이것을 구현했지만 개념은 다른 플랫폼에서도 작동합니다.

기본적으로 나는 짧은 (5 분) 하나의 토큰과 일주일 후에 만료되는 긴 토큰 두 개를 발행합니다. 클라이언트 라이브러리는 미들웨어를 사용하여 일부 요청에 대해 401 응답을 수신하면 짧은 토큰을 한 번 새로 고칩니다. 그런 다음 원래 요청을 다시 시도하고 새로 고칠 수 있으면 사용자에게 투명하게 올바른 응답을받습니다. 실패하면 401을 사용자에게 보냅니다.

짧은 토큰이 만료되었지만 여전히 유효하고 긴 토큰이 유효하고 확실한 경우, 긴 토큰이 인증하는 서비스의 특수 엔드 포인트를 사용하여 짧은 토큰을 새로 고칩니다 (이것이 사용할 수있는 유일한 것임). 그런 다음 짧은 토큰을 사용하여 새로운 긴 토큰을 가져 와서 짧은 토큰을 새로 고칠 때마다 1 주일 더 연장합니다.

이 방법을 사용하면 최대 5 분 이내에 액세스를 취소 할 수 있으며 이는 블랙리스트 토큰을 저장하지 않고도 사용할 수 있습니다.

후기 편집 : 머릿속에서 새로 나온 후이 달을 다시 읽으면 짧은 토큰을 새로 고칠 때 더 비싼 통화 (예 : 데이터베이스에 전화하여 사용자가 있는지 확인)를 할 수 있기 때문에 액세스를 취소 할 수 있음을 지적해야합니다 귀하의 서비스를 호출 할 때마다 비용을 지불하지 않고 금지되었습니다.


답변

다음은 JWT 액세스 토큰을 취소하는 단계입니다.

1) 로그인시 client에 대한 응답으로 2 개의 토큰 (Access token, Refresh token)을 보냅니다.
2) 액세스 토큰의 만료 시간이 줄어들고 새로 고침의 만료 시간이 길어집니다.
3) 클라이언트 (프론트 엔드)는 로컬 저장소에 새로 고침 토큰을 저장하고 쿠키에 토큰을 액세스합니다.
4) 고객은 API 호출에 액세스 토큰을 사용합니다. 그러나 만료되면 로컬 저장소에서 새로 고침 토큰을 선택하고 인증 서버 API를 호출하여 새 토큰을 가져옵니다.
5) 인증 서버에는 API가 노출되어 새로 고침 토큰을 수락하고 유효성을 검사하고 새 액세스 토큰을 반환합니다.
6) 새로 고침 토큰이 만료되면 사용자가 로그 아웃됩니다.

자세한 내용이 필요하면 알려주십시오. 코드 (Java + Spring boot)도 공유 할 수 있습니다.