2017-01-24 11 views
0

Cross Origin Ajax 클라이언트에서받은 json 웹 토큰의 Node.js 서버 유효성 검사를 진행하고 있습니다. 아마도 토큰은 다음 어떤 상태 Google OpenID Connect에 의해 생성됩니다Google의 OpenID Connect 검색 문서에서 공개 키의 캐시를 유지하는 방법

구글의 오픈 ID 연결 서비스를 사용하려면, 당신은 하드 코드 응용 프로그램에 Discovery-document URI해야한다. 응용 프로그램은. 서를 페! 한 다음 필요에 따라 엔드 포인트 URI를 검색합니다.

검색 문서의 값을 캐싱하여 HTTP 왕복을 피할 수 있습니다. 표준 HTTP 캐싱 헤더가 사용되며이를 준수해야합니다.

소스 : https://developers.google.com/identity/protocols/OpenIDConnect#discovery

은 내가 캐시 키를 저장할 어디 keyCache 사전에 약간의 타임 스탬프 속성을 추가 할 키와 moment.js를 얻을 수 request.js을 사용하여 다음과 같은 기능을 썼다. 이 함수는 서버가 시작될 때 호출됩니다.

function cacheWellKnownKeys(uri) { 
    var openid = 'https://accounts.google.com/.well-known/openid-configuration'; 

    // get the well known config from google 
    request(openid, function(err, res, body) { 
    var config    = JSON.parse(body); 
    var jwks_uri    = config.jwks_uri; 
    var timestamp   = moment(); 

    // get the public json web keys 
    request(jwks_uri, function(err, res, body) { 
     keyCache.keys   = JSON.parse(body).keys; 
     keyCache.lastUpdate = timestamp; 
     keyCache.timeToLive = timestamp.add(12, 'hours'); 
    }); 
    }); 
} 

키를 성공적으로 캐시하면 이제는 시간이 지남에 따라 캐시를 효과적으로 유지하는 방법에 관한 것이됩니다.

Google은 공개 키를 자주 변경하지 않으므로 (하루에 한 번만) 캐시 할 수 있으며 대다수의 경우 로컬 유효성 검사를 수행 할 수 있습니다.

소스 :https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken

구글은 매일 자신의 공개 키를 변경되기 때문에, keyCachetimestamptimeToLive 특성을 가진 내 생각은 두 가지 중 하나를 수행하는 것입니다

  1. 세트 캐시를 업데이트하는 데 12 시간마다 한 번의 시간 초과가 발생합니다.
  2. Google이 공개 키를 12 시간 내 사이클을 pdate하십시오. 내 마지막에 실패한 토큰 유효성 검사는 키 캐시를 새로 고치고 마지막으로 토큰의 유효성 검사를 한 번 시도합니다. 나는 캐시를 업데이트하는 동안 잘 알려진 설정 및 공개 키에 반복 왕복 결과 유효하지 않은 토큰 요청의 공격을 고려 할 때까지

이 가능한 작업 알고리즘처럼 보인다.

아마도 네트워크 오버 헤드가 줄어들 수있는 더 좋은 방법이있을 것입니다. 위의 첫 번째 인용문에서이 한 줄보다 효율적인 솔루션을 개발하고 함께 할 수있는 뭔가가있을 수 있습니다하지만 난 그것에 대해 무엇을 할 확실하지 않다 : 그냥이 ... Standard HTTP caching headers are used and should be respected.

을 내 질문은 정말 생각

Google 검색 문서의 HTTP 캐싱 헤더를 활용하여보다 효율적인 캐싱 솔루션을 개발해야합니까? 어떻게 작동할까요?

답변

1

discovery document은 공개 키가있는 다른 문서의 웹 주소 인 jwks_uri입니다.이 다른 문서는 그들이 말할 때 언급하는 것입니다 ...

표준 HTTP 캐싱 헤더가 사용되고 존중되어야합니다.

https://www.googleapis.com/oauth2/v3/certs 다음 헤더 알이 주소에 HTTP HEAD 요청 :

HTTP/1.1 200 OK 
Expires: Wed, 25 Jan 2017 02:39:32 GMT 
Date: Tue, 24 Jan 2017 21:08:42 GMT 
Vary: Origin, X-Origin 
Content-Type: application/json; charset=UTF-8 
X-Content-Type-Options: nosniff 
x-frame-options: SAMEORIGIN 
x-xss-protection: 1; mode=block 
Content-Length: 1472 
Server: GSE 
Cache-Control: public, max-age=19850, must-revalidate, no-transform 
Age: 10770 
Alt-Svc: quic=":443"; ma=2592000; v="35,34" 
X-Firefox-Spdy: h2 

프로그래밍 방식 request.js하여 응답 객체 생성에서 이러한 헤더 필드를 액세스하고 여기에서 최대 사용 기간 값을 구문 분석을, 다음과 같이 입력하십시오 :

var cacheControl = res.headers['cache-control'];  
var values = cacheControl.split(','); 
var maxAge = parseInt(values[1].split('=')[1]); 

maxAge 값은 초 단위로 측정됩니다. 그런 다음 maxAge (밀리 초 변환에 대해 1000 회)를 기준으로 시간 초과를 설정하고 모든 시간 초과 완료시 캐시를 재귀 적으로 새로 고치는 것이 좋습니다. 이렇게하면 잘못된 모든 인증 시도에서 캐시를 새로 고치는 문제가 해결되고 moment.js로 수행중인 타임 스탬프를 삭제할 수 있습니다.

이러한 잘 알려진 키의 캐싱을 처리하기 위해 다음 기능을 제안합니다.

var keyCache = {}; 

/** 
* Caches Google's well known public keys 
*/ 
function cacheWellKnownKeys() { 
    var wellKnown= 'https://accounts.google.com/.well-known/openid-configuration'; 

    // get the well known config from google 
    request(wellKnown, function(err, res, body) { 
     var config = JSON.parse(body); 
     var address = config.jwks_uri; 

     // get the public json web keys 
     request(address, function(err, res, body) { 

      keyCache.keys = JSON.parse(body).keys; 

      // example cache-control header: 
      // public, max-age=24497, must-revalidate, no-transform 
      var cacheControl = res.headers['cache-control'];  
      var values = cacheControl.split(','); 
      var maxAge = parseInt(values[1].split('=')[1]); 

      // update the key cache when the max age expires 
      setTimeout(cacheWellKnownKeys, maxAge * 1000);  
     }); 
    }); 
}