-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecode-verify-jwt.js
70 lines (67 loc) · 3.09 KB
/
decode-verify-jwt.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
except in compliance with the License. A copy of the License is located at
http://aws.amazon.com/apache2.0/
or in the "license" file accompanying this file. This file is distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under the License.
*/
var https = require('https');
var jose = require('node-jose');
var region = 'us-east-2';
var userpool_id = 'us-east-2_V5r07zvBM';
var app_client_id = '4qms54ir1t0krrp2bepvgh7doj';
var keys_url = 'https://cognito-idp.' + region + '.amazonaws.com/' + userpool_id + '/.well-known/jwks.json';
exports.handler = (event, context, callback) => {
var token = event.token;
var sections = token.split('.');
// get the kid from the headers prior to verification
var header = jose.util.base64url.decode(sections[0]);
header = JSON.parse(header);
var kid = header.kid;
// download the public keys
https.get(keys_url, function(response) {
if (response.statusCode == 200) {
response.on('data', function(body) {
var keys = JSON.parse(body)['keys'];
// search for the kid in the downloaded public keys
var key_index = -1;
for (var i=0; i < keys.length; i++) {
if (kid == keys[i].kid) {
key_index = i;
break;
}
}
if (key_index == -1) {
console.log('Public key not found in jwks.json');
callback('Public key not found in jwks.json');
}
// construct the public key
jose.JWK.asKey(keys[key_index]).
then(function(result) {
// verify the signature
jose.JWS.createVerify(result).
verify(token).
then(function(result) {
// now we can use the claims
var claims = JSON.parse(result.payload);
console.log(claims);
// additionally we can verify the token expiration
var current_ts = Math.floor(new Date() / 1000);
if (current_ts > claims.exp) {
callback('Token is expired');
}
// and the Audience (use claims.client_id if verifying an access token)
if (claims.client_id != app_client_id) {
callback('Token was not issued for this audience');
}
callback(null, claims);
}).
catch(function() {
callback('Signature verification failed');
});
});
});
}
});
}