AWS Cognito托管UI登录后无法从URL获取id_token与access_token
AWS Cognito托管UI登录后无法提取令牌的解决方法
问题现象
- 登录完成后,重定向URL包含
#id_token、#access_token等令牌信息,但通过Python的requests.url仅能获取http://localhost:5000/upload,哈希段(#之后的内容)完全丢失 - 尝试用Python按
#分割URL时,触发索引越界错误
示例重定向URL
http://localhost:5000/upload#id_token=eyJraWQiOiJDOWtTMmxRXC9VQ2hwN3lNVnY1YWtuU0N5M245Wm1UVG1Dempvd2c1Mm9SUT0iLCJhbGciOiJSUzI1NiJ9.eyJhdF9oYXNoIjoiQzRSZUw2QUthdkkyOU02UERjakRIQSIsInN1YiI6IjZlYzY0OTA1LTBjY2EtNDdmZi05ZWE0LWQyNjIwNDFmNjY5NiIsImNvZ25pdG86Z3JvdXBzIjpbInVzLWVhc3QtMl9hMk11UkxLU0tfR29vZ2xlIl0sImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tXC91cy1lYXN0LTJfYTJNdVJMS1NLIiwiY29nbml0bzp1c2VybmFtZSI6Imdvb2dsZV8xMDQ5NjExMDExODQ2ODQ2Mjk5MDciLCJhdWQiOiIxYnUxMHNxcW4zYjJnZDQ1ZWRlcGRsMGdpZSIsImlkZW50aXRpZXMiOlt7InVzZXJJZCI6IjEwNDk2MTEwMTE4NDY4NDYyOTkwNyIsInByb3ZpZGVyTmFtZSI6Ikdvb2dsZSIsInByb3ZpZGVyVHlwZSI6Ikdvb2dsZSIsImlzc3VlciI6bnVsbCwicHJpbWFyeSI6InRydWUiLCJkYXRlQ3JlYXRlZCI6IjE2ODQwNjg0NTAwMzkifV0sInRva2VuX3VzZSI6ImlkIiwiYXV0aF90aW1lIjoxNjg0MTM4MTkwLCJleHAiOjE2ODQxNDE3OTAsImlhdCI6MTY4NDEzODE5MCwianRpIjoiZWM4NjdlMDItZGViNC00NDc3LWExYzItYTE1NzljZGM1YjYwIiwiZW1haWwiOiJjcmFuaXJ1ZGRocWFAZ21haWwuY29tIn0.VBd4aVzh7Lk2TxAtqrG9rC1oOe05d5Kh7Z0Yx6DEeQaJm3M8IL9V1IYBynC51oRXVmxowfZEuppzJSxlNaHg6u6Gpc6ICO7QV9F9CH1YYmnXJmQlSEhN95gbCG7E8NmyjsWh_0DL1aByWw9A08tAL5A-fgzUVaS7Hl28XHAmVdEvkc_ZpWo9zfYSs1-UX9OV_SqO0vKiu3-ZcZPj7471eyC4OYexRKBkevom7JDhg_0GLlnoxk1NpVxQa_lvlle_l_YlEJXMbMQ5vRgZr22ooVtXlmjz_jQTv16Jw_rcGEOEXo4mYC40ePyYc-Lw9HGnHI1sWDEbYMzhdcihRWc08w&access_token=eyJraWQiOiJQaDBHRVQrSStyTjRaZnloOHJKekM2aHhwYURwUmlFaU5ZMVlZRlQ0M2FjPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI2ZWM2NDkwNS0wY2NhLTQ3ZmYtOWVhNC1kMjYyMDQxZjY2OTYiLCJjb2duaXRvOmdyb3VwcyI6WyJ1cy1lYXN0LTJfYTJNdVJMS1NLX0dvb2dsZSJdLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0yLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMl9hMk11UkxLU0siLCJ2ZXJzaW9uIjoyLCJjbGllbnRfaWQiOiIxYnUxMHNxcW4zYjJnZDQ1ZWRlcGRsMGdpZSIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJhdXRoX3RpbWUiOjE2ODQxMzgxOTAsImV4cCI6MTY4NDE0MTc5MCwiaWF0IjoxNjg0MTM4MTkwLCJqdGkiOiI2ODRmNjVmMS0yMTI4LTRiYzctOGRmNi0wMzI4NjA5ZjFkN2IiLCJ1c2VybmFtZSI6Imdvb2dsZV8xMDQ5NjExMDExODQ2ODQ2Mjk5MDcifQ.HdVnOiGuLS3ZjEb6XaMQHSGizqwrimIShq2xfuRtMBOdudblhTBMjSeQReqcOoGt2YRRiDGVpdGWE2-jhXAGEK-Z-0SDR1WmGnTgslwj8vQQjvRhX2JYtzKwClJ68dT427Jhe6m1_aJAOx0inzXM57FQDUrzRMLf4kv5JsF6Xm1mBOMWOmnQye7cbyaAhwKNGGQkVfY37XBCbHBVRhtwEc01HXpLX5TEbNytz73sobURu7YrB1_a4qPH49ZNHzIlM6k3sVSPIuRC6I7ynAlI-T9eAFTa0H9bvsKZLNNMDbHJmcKT1yOZuNfoaAlhHfvoXnSRcf7L5tciHHgQNOMcTA&expires_in=3600&token_type=Bearer
原Domain字符串
f'https://******.auth.us-east-2.amazoncognito.com/login?client_id=**********&response_type=token&scope=openid&redirect_uri=http://localhost:5000/callback'
问题原因
HTTP协议规定,URL中的哈希段(#之后的内容)仅由客户端浏览器处理,不会发送给服务器。因此后端通过requests获取到的URL不包含这部分内容,自然无法通过分割#提取令牌。
解决方案
方案1:前端直接提取(推荐)
在前端页面中,通过JavaScript直接读取浏览器的location.hash并解析:
// 前端代码示例 const hashContent = window.location.hash.slice(1); // 移除开头的# const tokenParams = new URLSearchParams(hashContent); const idToken = tokenParams.get('id_token'); const accessToken = tokenParams.get('access_token');
方案2:后端使用授权码流程获取令牌
修改Cognito的登录请求参数,将response_type=token改为response_type=code,使用授权码模式获取令牌:
- 修改Domain字符串:
f'https://******.auth.us-east-2.amazoncognito.com/login?client_id=**********&response_type=code&scope=openid&redirect_uri=http://localhost:5000/callback'
- 后端获取授权码并换取令牌:
import requests # 从请求参数中获取授权码 auth_code = requests.args.get('code') # 向Cognito令牌端点发送请求 token_endpoint = 'https://******.auth.us-east-2.amazoncognito.com/oauth2/token' payload = { 'grant_type': 'authorization_code', 'client_id': '**********', 'code': auth_code, 'redirect_uri': 'http://localhost:5000/callback' } # 发送POST请求获取令牌 response = requests.post(token_endpoint, data=payload) token_data = response.json() id_token = token_data.get('id_token') access_token = token_data.get('access_token')
内容的提问来源于stack exchange,提问作者animo
相关产品推荐
相关产品推荐

