I Tried Adding Google Auth To a Python Web App | ft. Streamlit
Summary
TLDRIn this video, the creator shares a month-long journey of researching and building multiple Streamlit apps with Google authentication methods. Despite testing various solutions, none proved entirely satisfactory without delving into the authentication workflow. The video guides viewers through the Google authentication process, explaining how to create credentials, configure consent windows, and handle OAuth scopes. It explores different authentication techniques, including using Python libraries like Google-auth and FastAPI, and discusses the challenges of implementing these in Streamlit Cloud. The creator also touches on advanced topics like session-based authentication, token management, and the use of reverse proxies for production settings, offering insights into best practices for secure and efficient app development.
Takeaways
- 🔍 The video discusses the process of researching and building streamlit apps with Google authentication, testing various methods to find a satisfying solution.
- 🔑 It highlights the necessity of creating keys in a Google Cloud project to access Google APIs and user data.
- 🛠️ The script guides through configuring the consent window to access resources like Gmail, profile pictures, and calendar events.
- 📝 It mentions the importance of understanding OAuth 2.0 and OpenID Connect for securely accessing user data without handling passwords.
- 💻 The video demonstrates using the Google OAuth library to authenticate and access user information through a local server.
- 🚫 It points out limitations when deploying on streamlit cloud, such as the inability to spawn new processes or expose certain ports.
- 🌐 The script explores using FastAPI to handle authentication callbacks and create a more flexible server-side solution.
- 🔄 It discusses session-based authentication, the use of access tokens, and the importance of refresh tokens for maintaining user sessions.
- 🍪 The video addresses the need for cookie management and user consent, especially regarding GDPR and privacy regulations.
- 🔗 It suggests alternative authentication methods, such as using a reverse proxy or authentication-as-a-service providers for more robust solutions.
Q & A
What is the main challenge the video aims to address?
-The video addresses the challenge of finding a satisfying, one-size-fits-all solution for Google authentication in streamlit apps without deep involvement in the authentication workflow.
Why is it necessary to create keys to access Google services?
-Keys are necessary to access Google services because they act as credentials that grant your application permission to access user data like Gmail, profile pictures, and other Google resources.
What is the role of the consent screen in the Google authentication process?
-The consent screen is where you configure the app's metadata and specify the resources (scopes) your app can access, such as user info, email, and profile. It also sets up the user consent flow for accessing these resources.
What are the limitations of using 'get_user_credentials' method in streamlit cloud?
-The 'get_user_credentials' method cannot be used in streamlit cloud due to limitations like inability to spawn new processors, remote streamlit app's inability to access the local browser, and the non-exposure of port 9000 by the container.
What is the difference between OAuth and OpenID Connect mentioned in the script?
-OAuth is a protocol for secure API access delegation, while OpenID Connect is a simple identity layer on top of OAuth 2.0. They are used for building clients that can securely access user data without handling passwords.
Why is the 'authorization code grant type flow' used in the video?
-The 'authorization code grant type flow' is used because it is the most common authentication flow on the web, allowing the app to obtain an access token by presenting an authorization code received from the authorization server.
What is the significance of the 'state' parameter in the authentication flow?
-The 'state' parameter is a randomly generated ID that helps prevent CSRF attacks by ensuring that the response from the authorization server matches the original request from the client.
How does the video suggest handling tokens after user authentication?
-The video suggests using session-based authentication, where tokens are stored in a database and an HTTP-only secure cookie is used to manage user sessions without exposing sensitive tokens to the client-side.
What are the privacy considerations when using cookies for authentication?
-Cookies are considered browser tracking under GDPR, so consent is required from users to store cookies. The video highlights the need to manage cookies carefully, especially when deploying apps for public use.
What alternative authentication techniques are mentioned in the video?
-The video mentions using authentication as a service providers like Auth0 or Firebase, and using a reverse proxy like Nginx or Caddy to manage authentication and user sessions.
Outlines
🔑 Unlocking Google Authentication Workflow
The narrator discusses the challenges of creating a satisfying Google authentication solution after trying various methods. The main point is about understanding the Google authentication workflow by configuring a dedicated Google Cloud project. This involves setting up OAuth consent, choosing appropriate scopes for accessing user data, and the process of creating OAuth client credentials. The narrator emphasizes the importance of understanding the workflow rather than relying on a one-size-fits-all solution.
🖼️ Displaying Google User Info in a Streamlit App
The narrator explains how to display user information such as name, email, and profile picture in a Streamlit app after completing the authentication flow. They also demonstrate how the Google Calendar API can be accessed using an authorization token. The challenge with Streamlit Cloud is highlighted—limitations like the inability to spawn new Flask servers, open browser tabs, or expose certain ports. The narrator switches to FastAPI for local server operations, setting up a new callback URL and explaining how to capture and process the authorization flow.
🔄 Session Management and Token Handling with FastAPI
In this paragraph, the narrator discusses pushing their minimal viable product (MVP) further by integrating session-based authentication. They explain how to create new authorization URLs, store session states in a database, and handle secure cookies. The narrator describes the process of using FastAPI to manage session tokens and ensure that access and ID tokens are properly stored and reused in future interactions, emphasizing the importance of backend token management for security.
💡 Alternative Solutions and Front-End Google Widgets
The narrator introduces an alternative front-end approach to Google authentication using embedded Google sign-in buttons. This method reduces the need for FastAPI or backend token handling by utilizing Streamlit components to handle the Google token via JavaScript. They point out limitations, such as restrictions in Streamlit Cloud, and explain how to modify OAuth credentials for local testing. The narrator reflects on the pros and cons of different authentication techniques and promises to explore further solutions in future videos, including reverse proxies like NGINX for production environments.
Mindmap
Keywords
💡Google Authentication
💡OAuth
💡Client ID and Secret
💡Scopes
💡Consent Screen
💡Callback URL
💡Streamlit
💡FastAPI
💡Authorization Code Grant
💡Refresh Token
💡Session-based Authentication
Highlights
The speaker has been researching and building streamlit apps with Google auth for a month.
No single solution for Google authentication in streamlit was found to be fully satisfying.
The necessity to understand the Google authentication workflow is emphasized.
A guide on creating Google Cloud credentials to access user data is provided.
The importance of configuring the consent window for accessing user resources is discussed.
The process of creating an OAuth client ID for a web application is explained.
The limitations of using Google authentication in streamlit cloud are highlighted.
The use of Python libraries like requests-oauthlib for authentication is mentioned.
The installation and use of the Google OAuth library in streamlit is described.
A detailed walkthrough of the Google authentication flow using 'get_user_credentials' is provided.
The concept of web application flow or authorization code grant type flow is introduced.
The challenges of using Google authentication in streamlit cloud due to Docker limitations are discussed.
An alternative method using FastAPI to handle Google authentication callbacks is presented.
The implementation of session-based authentication to manage user sessions is explained.
The use of refresh tokens to renew access tokens is mentioned.
The speaker discusses the implications of GDPR on cookie usage for authentication.
The exploration of using a front-end Google sign-in button within streamlit is described.
The speaker's personal preference for server-side solutions over front-end for authentication is shared.
The potential of using reverse proxies like Caddy for managing authentication in streamlit apps is mentioned.
The video concludes with a teaser for future content on hosting streamlit apps with Caddy.
Transcripts
it's been a month since I started
researching for this video and I built
seven to eight different streamid apps
with various Google art methods but
after testing all of the solutions none
felt truly satisfying data fans I find
it hard to recommend a one- siize fitall
solution that doesn't involve digging
into the authentication workflow so
instead let me walk you through the
solutions I tried so you understand the
Google authentication workflow and can
confidently work you those libraries
yourself but before trying any Google
signin Technique we need to create the
keys to access the Google Kingdom in a
dedicated Google Cloud project head to
the credentials page under apis and
services to access user data like the
name gmail profile picture and Google
resources like calendar meetings you
first need to configure the consent
window to access the resources find the
oot consent screen edit your apps
metadata the name website developer
email and logo on the next page click
add Scopes and select the resources you
want the app to access it would be the
open ID user info email and profile
Scopes and if you enable the calendar
API beforehand you can also scroll to
select the Google calendar events read
only
scope Scopes are categorized by
sensitivity it doesn't matter for local
testing but if you release your app to
the world it needs to go through a
Google very ification process first
which will be more difficult depending
on how many sensitive Scopes you are
asking
for while you are in testing mode you
can add friends and family Google emails
as beta testers to log your
app next create a new o client ID
credential for our web
application the Google authorization
server needs a path back to your
extremely app to send back a code for
now provide HTTP Local Host 9000 as a
call back address we will think later
about how to listen to it a new client
ID and secret will be created copy those
into streamlet secret TL file then
download the Json secret file to the
root of your project it will act as our
passport to the Google Gates we are
ready to
authenticate four weeks ago I looked for
python authentication libraries and I
found options like request Quest o or
off Li for building o 2/ open ID connect
clients at this point I kept reading
those two terms everywhere we just set o
to keys with open ID Scopes platforms
like GitHub Twitter and Google provide o
to endpoints to let python apps securely
access user data tools like Solara and
panel simplify OD to configuration for
their developers it's like if your
python web app has to access user info
from a website without manipulating p
password you should look into o 2/ oidc
documentation i p installed the Google o
o Library it includes the get user
credentials method taking as input the
client ID client secret and a subset of
access copes we defined in the consent
screen earlier you can also indicate a
minimum and maximum port for demo
purposes I limited to Port
9,000 I trust you remember where we
configured local lost 9,000
when I click the login button streamly
calls get user credentials and opens a
new browser tab for me there's the
authorization URL it opened for me data
fans we are not on my Stream app anymore
we are interacting with Google's
authorization server if I'm not signed
in with a Google account it displays a
new Google signin window let me enter my
Gmail
credentials I am the only test user that
can authenticate with this clent ID
anyway I added myself as the only beta
tester while this app is not verified
then on the next window the Google
authorization server asks me the user to
confirm the app can access the resources
from the subset of Scopes like my name
or my Google Calendar oh yes I I accept
authentication flow
successful and I receive a credentials
object back in Python without ever
handling Google passwords in my code I'm
I am not a hacker who tries to steal
your Google
passwords the credential contains a few
interesting objects but right now I only
need user information provided by the
open ID connect scope so I extract the
ID token from the
credentials there is a procedure to
decode and verify the authenticity of
the token just in case someone corrupted
it with a scam
email and now I have access to my user's
name my verified Gmail address and my L
to my profile picture which are pretty
easy to display in My Stream app and
store in a database for future
usage since the Google Calendar read
scope is included in the flow I can even
use the access token in the credentials
as an ID card to read the user's Google
Calendar this is the easiest solution to
authenticate with Google and access your
Google resources from streamlet
unfortunately it won't work on streamid
cloud the process looks a bit opaque at
first but under the hood get user
credential runs a local flash server
that listens on local
9000 however the docker image for stream
cloud has three limitations first I
cannot spawn new processors to M Bitcoin
I mean I cannot spawn a new flask server
that listens to Port 9000 second the
remote streamit app cannot access my
local browser to open a new tab and
third the port 9000 isn't exposed by the
container if you really need this
solution you're better off deploying
your own Docker image in another cloud
service can't I just use streamlets
tornado server instead unfortunately as
of this videoos released there is no
native way to get the tornado instance
and tell it to listen to another
endpoint so maybe I should just spin you
know my own python server to listen to
Port 9,000
right so I install fast API why fast API
instead of flask no reason just because
no reason fast API opens on Port 8,000
by default I could have changed the
command line to run on Port 9,000 but
instead I added Local Host 8000 sl/ code
as a new callback URL for my o clients I
don't think it's a good practice to
stuff many up callbacks in a o clients
it could crumble under so many
responsibilities anyway I Define a new
get/ out/ code and point in fast API and
run the app next to streamlit to catch
any call back to local lost
8000
code back to my streamit app I create a
new o flow to generate a Google
authorization URL and states it is a
randomly generated ID that is baked into
the authorization URL and and sent to
Google's authorization
server I kind of consider this as the ID
of the current authentication flow and I
expect the authorization server to keep
it in mind then I embed the
authorization URL into a link button
which redirects the user to Google's old
servers on a click so far we're in known
territory as always I input my Gmail
account consent to let it use my profile
info press okay then
instead of the authentication is a
success text I'm getting back the hello
world from Fast
API so after the logging and consent
screen the Google authorization server
sends back a response to the Callback
URL which fast API catches you know
might as well play with this call back I
add a state and code argument to fast
API so it parses them out of the request
and then I just display them in HTML
response
and look at this the state and code gets
passed into my
HTML
nice let's try a new authentication flow
in streamlet and see F API catch the
authorization call
back you can use this code to get your
credentials from the Google resource
server but be quick agent fan this code
will self-destruct in 5 minutes I create
a new form in streamlit to copy paste
the state and code back from Fast API if
the state ID from the origin stream need
and the Google authorization server
called back to fast API match I know
they come from the same flow so this
temporary authorization code is for me
and I can use it to Ping the Google
resource server for user credentials
using the fetch token
method and then like last time I extract
and verify the ID token from the
credentials to get the logged in user
yada yada
yep that's the full a to workflow
breakdown behind get user credentials
this is the most common authentication
flow on the web it's called the web
application flow or authorization code
Grant type flow it's the default flow in
any python o web library but I I still
have a few questions for for example
what do I do with those credentials
after reading user info from the ID
should I like store the credentials
somewhere so I can reload them when the
user comes back to the session and if a
hacker steals the access token can they
read my Google Calendar for secret
meetings with my manager to answer those
questions I pushed my MVP a little
further maybe too much so I won't show
the full code but the project is in the
description
[Music]
below I added a/ session endpoint in
fast API that creates a new autois ation
URL and state ID I store this state in a
local SQL light or a remote fir store
database stream L calls this to create a
session on Fast API and in the database
and get the authorization URL with a
button click and a redir hack I push the
user to the Google authorization URL for
login and
consent the Google OD server calls back
fast API which passes the call back URL
for the state and authorization code
and if the state ID is in the database
it uses the code to fetch the access and
ID tokens from the resource
server finally fast API sends a redirect
response back to streamlets and stores
the state ID in an HTTP only secure
cookie on my
browser cookies well since stre 1.37
streamlet can read cookies with the St
context cookies method so on each return
to streamlet I can read the state from
the cookie send it to fast API to check
if there's a matching session and if one
exists reuse the tokens from the session
in the database to get back calendar and
profile
information that way sensitive tokens
are never sent to the client
browser I later discovered that this is
called session based authentication it's
fun to implement once in your life but
uh it just opens a new batch of troubles
if backend development is not your
specialty for example because this
access token has so much power in
accessing user resources it has a very
short lifespan in case it gets stolen at
least we are lucky since those tokens
stay on the backend tornado server side
in stream we don't display them in any
front end code and actually because of
the short lifespan of an access token
there is a third token in the
credentials objects that I didn't talk
about it's called the refresh token in
case the access token expires I should
use the refresh token to renew the
access token instead of going through a
new login flow speaking of login flows
and cookies you know gdpr privacy don't
track people putting a cookie is
considered browser tracking and if I
deploy my app to the world I am supposed
to ask for consent to store the cookie
on the user's browser and I'm sure I
will forget to do it yep anyway as a
data expert that's a lot of tokens
sessions and cookies to deal
with this video is sponsored by myself
if you want to support me researching
editing and showcasing the latest data
and web practices for data fans consider
buying me a coffee to stay awake or
offer a super tanks after I show you the
next authentication technique that
doesn't require fast API let's go if we
have a hard time doing back and forth
server side interaction in streamlet why
not do everything on the front and side
that's when it appeared to me the
ultimate Google widgets I found a Google
signin button that could be embedded in
HTML JavaScript
code elegant fact by using a stream
component I can embed the HTML Google
sign in button in my web app catch the
Google token in the JavaScript call back
and push the token back into server side
tornado python code then finally I use
Google o o off slip whatever verify
token to extract the token
ID it works as long as I add the Streit
locost 8501 URL to the list of
authorized origins in my o credentials
on the Google console no fast API server
needed no back and forth between the
authorization and the resource no
storing and comparing session tokens
Google does all of the hard stuff for
you actually if you look into your local
cookies you will find out a new sidcc
cookie from a Google origin sidcc
for session ID secure HTTP only cross
site
cookie if if you're interested I'm using
this component template from Thiago one
of the streid founders and you can find
the source code in the description below
again okay does it work on streamid
cloud well the logging and consant
Screen don't
load see if I check the web def tools
console it tells me the given origin is
not allowed for the given client ID let
me add the URL to the list of JavaScript
Origins and wait a few minutes again
okay uh let's try
again
yep we've seen three different
techniques to do Google authentication
that work well in low stakes
environments I personally use the get
user credentials locally or on an on
premise server for quick login for
example for my YouTube analytics
dashboard
it sounds like the signin button
component is a better beginner friendly
solution especially if you have access
to the HTML CSS JavaScript which is not
really the case in streamlit and I know
I'm too lazy to maintain JavaScript
logic in the long run so I tend to stick
with python based server side solutions
for more flexibility or fine-tuning
deploying your own fast API server to
catch the authentication flow is a nice
setup as long as you to put https
everywhere there are two more solutions
that didn't make it in this video
because it's already too long but do
tell me in the comments if you want a
second one the first one is the
authentication as a service path you can
use o providers like o zero Fire based
authentication or super based to manage
a unique single sign on with multiple
identity providers use the data and
session cookie management for you they
even have their dedicated UI for example
here's Solara o method redirecting to an
old zero logging and streamid Cloud
redirects you to Old kits
UI a second ID commonly used in
production settings it's even
recommended as a best practice in the
Unicorn documentation for deploying
flask is to put your streamit app behind
a reverse proxy like engine INX or caddy
the reverse proxy handles load balancing
caches static files and most importantly
manages our authentication via Solutions
like authentic aelia or keycloak it then
redirects the logged in user to the
Stream It app with a HTTP header to
identify them just like cookies starting
version
1.37 streamlet can access headers
through the St context headers method to
access user information passed by the
reverse proxy so we're good nope
now I'm off to play with caddy as a
reverse proxy for streamlit and if it
goes well maybe I should plan a video
about hosting streamit apps in pseudo
production settings with caddy so you
know I'll see you
around bye
浏览更多相关视频
Oauth2 JWT Interview Questions and Answers | Grant types, Scope, Access Token, Claims | Code Decode
API Authentication with OAuth using Azure AD
Next.js App Router Authentication (Sessions, Cookies, JWTs)
#38 Spring Security | Validating JWT Token
Serverless Auth with Lucia Auth V3
Learn JWT in 10 Minutes with Express, Node, and Cookie Parser
5.0 / 5 (0 votes)