Skip to content

Commit 47f5936

Browse files
authored
Add id_token to OIDC cookie exchange for frontend logout (#697)
- Store id_token in HTTP-only cookie during OIDC callback - Include id_token in token exchange response to frontend - Clear id_token cookie after exchange - Enables frontend to use id_token_hint for proper OIDC logout
1 parent e6eabbd commit 47f5936

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

gramps_webapi/api/resources/oidc.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,18 @@ def get(self, args):
213213
path='/'
214214
)
215215

216+
# Store id_token if available (needed for OIDC logout)
217+
if token.get('id_token'):
218+
response.set_cookie(
219+
'oidc_id_token',
220+
token['id_token'],
221+
max_age=300, # 5 minutes
222+
httponly=True,
223+
secure=not is_development, # Allow HTTP in development
224+
samesite='Lax',
225+
path='/'
226+
)
227+
216228
logger.info(f"Set OIDC cookies, redirecting to {frontend_url}/oidc/complete")
217229
return response
218230

@@ -233,20 +245,28 @@ def get(self):
233245
# Get tokens from HTTP-only cookies
234246
access_token = request.cookies.get('oidc_access_token')
235247
refresh_token = request.cookies.get('oidc_refresh_token')
248+
id_token = request.cookies.get('oidc_id_token')
236249

237250
logger.info(f"Access token found: {bool(access_token)}")
238251
logger.info(f"Refresh token found: {bool(refresh_token)}")
252+
logger.info(f"ID token found: {bool(id_token)}")
239253

240254
if not access_token or not refresh_token:
241255
logger.error("No OIDC tokens found in cookies")
242256
abort_with_message(400, "No OIDC tokens found in cookies")
243257

244258
# Return tokens and clear cookies
245-
response = jsonify({
259+
response_data = {
246260
'access_token': access_token,
247261
'refresh_token': refresh_token,
248262
'token_type': 'Bearer'
249-
})
263+
}
264+
265+
# Include id_token if available (needed for OIDC logout)
266+
if id_token:
267+
response_data['id_token'] = id_token
268+
269+
response = jsonify(response_data)
250270

251271
# Clear the temporary cookies with same settings as when they were set
252272
frontend_url = get_config("FRONTEND_URL") or get_config("BASE_URL")
@@ -270,6 +290,15 @@ def get(self):
270290
samesite='Lax',
271291
path='/'
272292
)
293+
response.set_cookie(
294+
'oidc_id_token',
295+
'',
296+
expires=0,
297+
httponly=True,
298+
secure=not is_development,
299+
samesite='Lax',
300+
path='/'
301+
)
273302

274303
logger.info("OIDC token exchange successful, cookies cleared")
275304
return response

0 commit comments

Comments
 (0)