Skip to content

Commit 072e905

Browse files
fix (sign_jwt.py): invalid grant
1 parent ca5e451 commit 072e905

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

app/sign_jwt.py

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,29 @@ def gen_payload_data():
8787
8888
Avoids `invalid_grant` by getting a new `exp` value during signing
8989
"""
90-
9190
payload_data = {
92-
"audience": 'api.meetup.com',
93-
"kid": SIGNING_KEY_ID,
9491
"sub": SELF_ID,
95-
"iss": CLIENT_SECRET,
96-
"exp": time.time() + int(JWT_LIFE_SPAN)
92+
"iss": CLIENT_ID,
93+
"aud": "api.meetup.com",
94+
"exp": int(time.time() + JWT_LIFE_SPAN)
9795
}
98-
9996
return payload_data
10097

10198

10299
def sign_token():
103100
"""Generate signed JWT"""
104101

102+
# Define headers exactly as specified in docs
103+
jwt_headers = {
104+
"kid": SIGNING_KEY_ID,
105+
"typ": "JWT",
106+
"alg": "RS256"
107+
}
108+
105109
payload_data = gen_payload_data()
106110

107111
payload = jwt.encode(
108-
headers=headers,
112+
headers=jwt_headers,
109113
payload=payload_data,
110114
key=private_key,
111115
algorithm='RS256'
@@ -121,7 +125,8 @@ def verify_token(token):
121125
jwt.decode(
122126
jwt=token,
123127
key=public_key,
124-
issuer=CLIENT_SECRET,
128+
issuer=CLIENT_ID,
129+
audience="api.meetup.com",
125130
verify=True,
126131
algorithms=['RS256']
127132
)
@@ -134,6 +139,7 @@ def verify_token(token):
134139
jwt.exceptions.InvalidTokenError,
135140
jwt.exceptions.InvalidSignatureError,
136141
jwt.exceptions.InvalidIssuerError,
142+
jwt.exceptions.InvalidAudienceError,
137143
) as e:
138144
print(f"{Fore.RED}{error:<10}{Fore.RESET}{e}")
139145
sys.exit(1)
@@ -142,18 +148,30 @@ def verify_token(token):
142148
def get_access_token(token):
143149
"""Post token to auth server to get access token"""
144150

151+
# Headers for the token request
152+
request_headers = {
153+
"Content-Type": "application/x-www-form-urlencoded"
154+
}
155+
156+
# Payload exactly as specified in docs
157+
# https://www.meetup.com/api/authentication/#p04-jwt-flow-section
145158
payload = {
146-
"grant_type": 'urn:ietf:params:oauth:grant-type:jwt-bearer',
147-
"assertion": token,
148-
"redirect_uri": REDIRECT_URI,
149-
"client_id": CLIENT_ID,
150-
"client_secret": CLIENT_SECRET,
151-
"audience": 'api.meetup.com',
152-
"exp": time.time() + int(JWT_LIFE_SPAN)
159+
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
160+
"assertion": token
153161
}
154162
payload = urlencode(payload)
155163

156-
return requests.request("POST", TOKEN_URL, headers=headers, data=payload)
164+
try:
165+
response = requests.request("POST", TOKEN_URL, headers=request_headers, data=payload)
166+
response.raise_for_status()
167+
return response.json()
168+
except requests.exceptions.HTTPError as e:
169+
print(f"{Fore.RED}{error:<10}{Fore.RESET}HTTP Error: {e}")
170+
print(f"Response: {response.text}")
171+
return None
172+
except requests.exceptions.RequestException as e:
173+
print(f"{Fore.RED}{error:<10}{Fore.RESET}Request failed: {e}")
174+
return None
157175

158176

159177
def main():
@@ -163,12 +181,17 @@ def main():
163181
token = sign_token()
164182

165183
# verify JWT
166-
verify_token(token)
184+
if not verify_token(token):
185+
print(f"{Fore.RED}{error:<10}{Fore.RESET}Token verification failed")
186+
return None
167187

168188
# get access and refresh tokens
169-
res = get_access_token(token)
189+
tokens = get_access_token(token)
190+
if not tokens:
191+
print(f"{Fore.RED}{error:<10}{Fore.RESET}Failed to get access token")
192+
return None
170193

171-
return res.json()
194+
return tokens
172195

173196

174197
if __name__ == "__main__":

0 commit comments

Comments
 (0)