Summary
I have built a google sign in, as a must when anyone access the landing page - the code is incorporated in the landing page - it works fine - logs to google - comes back with user details and runs the functionality right - however - when I refresh the page I get - GetAccessTokenError: {‘error’: ‘invalid_grant’, ‘error_description’: ‘Bad Request’}
Steps to reproduce
Code snippet:
#imports here
import streamlit as st
import asyncio
from httpx_oauth.clients.google import GoogleOAuth2
# OAuth 2.0 Clients and secrets details
CLIENT_ID = "XXXX"
CLIENT_SECRET = "XXXXXX"
REDIRECT_URI = "http://localhost:8501"
async def get_authorization_url(client: GoogleOAuth2, redirect_uri: str):
authorization_url = await client.get_authorization_url(
redirect_uri, scope=["profile", "email"]
)
return authorization_url
async def get_access_token(client: GoogleOAuth2, redirect_uri: str, code: str):
token = await client.get_access_token(code, redirect_uri)
return token
async def get_email(client: GoogleOAuth2, token: str):
user_id, user_email = await client.get_id_email(token)
return user_id, user_email
client: GoogleOAuth2 = GoogleOAuth2(CLIENT_ID, CLIENT_SECRET)
# Check if user session exists
if "user_id" in st.session_state and "user_email" in st.session_state:
user_id = st.session_state.user_id
user_email = st.session_state.user_email
else:
user_id = None
# Check if access token is available in session state
if st.session_state.get("access_token", None) is None:
try:
# Get the code from the URL
code = st.experimental_get_query_params().get("code")
if code is None:
raise KeyError
# Get the access token
token = asyncio.run(get_access_token(client, REDIRECT_URI, code[0]))
st.session_state.access_token = token["access_token"] # Store access_token in session state
user_id, user_email = asyncio.run(get_email(client, token["access_token"]))
st.session_state.user_id = user_id
st.session_state.user_email = user_email
st.write(f"You're logged in as {user_email} and your id is {user_id}")
# Clear URL parameters
st.markdown(
"""
<script>
const url = new URL(window.location);
url.searchParams.delete("code");
window.history.replaceState({}, '', url);
</script>
""",
unsafe_allow_html=True,
)
except KeyError:
if user_id is None:
authorization_url = asyncio.run(
get_authorization_url(client, REDIRECT_URI)
)
st.sidebar.markdown(
f'<a target="_self" href="{authorization_url}">Login with Google</a>',
unsafe_allow_html=True,
)
else:
user_id, user_email = asyncio.run(get_email(client, st.session_state.access_token))
st.write(f"You're logged in as {user_email} and your id is {user_id}")
if user_id is None:
st.warning("Please log in to continue.")
st.stop()
# Rest of the code here that forms the landing page
Explain what you expect to happen when you run the code above.
- I would like refresh to maintain the session and open the landing page clear of any test inputs
Explain the undesired behavior or error you see when you run the code above.
GetAccessTokenError: {‘error’: ‘invalid_grant’, ‘error_description’: ‘Bad Request’}
Traceback:
File "C:\Users\bkant\AppData\Local\Programs\Python\Python39\lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 552, in _run_script
exec(code, module.__dict__)File "D:\AVA\SID-Project-Py\landing.py", line 54, in <module>
token = asyncio.run(get_access_token(client, REDIRECT_URI, code[0]))File "C:\Users\bkant\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)File "C:\Users\bkant\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 647, in run_until_complete
return future.result()File "D:\AVA\SID-Project-Py\landing.py", line 27, in get_access_token
token = await client.get_access_token(code, redirect_uri)File "C:\Users\bkant\AppData\Local\Programs\Python\Python39\lib\site-packages\httpx_oauth\oauth2.py", line 148, in get_access_token
raise GetAccessTokenError(data)
Debug info
- Streamlit version: Streamlit, version 1.24.1
- Python version: Python 3.9.13
- Using Conda? PipEnv? PyEnv? Pex? - PIP
- OS version: Windows 11
- Browser version: Chrome Version 114.0.5735.199 (Official Build) (64-bit)