Gradio provides several ways to add authentication to your app, from simple password protection to OAuth integration with Hugging Face and external providers.
Password-protected apps
You can add an authentication page in front of your app to limit who can access it. With the auth= keyword argument in the launch() method, you can provide a tuple with a username and password, or a list of acceptable username/password tuples.
Single user authentication
Here’s an example that provides password-based authentication for a single user named “admin”:
import gradio as gr
def greet(name):
return f"Hello {name}!"
demo = gr.Interface(greet, "textbox", "textbox")
demo.launch(auth=("admin", "pass1234"))
Multiple users
For multiple users, provide a list of tuples:
import gradio as gr
def greet(name):
return f"Hello {name}!"
demo = gr.Interface(greet, "textbox", "textbox")
demo.launch(auth=[
("alice", "password1"),
("bob", "password2")
])
Custom authentication function
For more complex authentication handling, pass a function that takes a username and password as arguments and returns True to allow access, False otherwise.
Here’s an example of a function that accepts any login where the username and password are the same:
import gradio as gr
def same_auth(username, password):
return username == password
def greet(name):
return f"Hello {name}!"
demo = gr.Interface(greet, "textbox", "textbox")
demo.launch(auth=same_auth)
User-specific content
If you have multiple users, you may wish to customize the content shown depending on the logged-in user. You can retrieve the logged-in user by accessing the network request directly and reading the .username attribute:
import gradio as gr
def update_message(request: gr.Request):
return f"Welcome, {request.username}"
with gr.Blocks() as demo:
m = gr.Markdown()
demo.load(update_message, None, m)
demo.launch(auth=[("alice", "password1"), ("bob", "password2")])
Logout functionality
If users visit the /logout page of your Gradio app, they will automatically be logged out and session cookies deleted. This allows you to add logout functionality to your app:
import gradio as gr
def update_message(request: gr.Request):
return f"Welcome, {request.username}"
with gr.Blocks() as demo:
m = gr.Markdown()
logout_button = gr.Button("Logout", link="/logout")
demo.load(update_message, None, m)
demo.launch(auth=[("alice", "password1"), ("bob", "password2")])
By default, visiting /logout logs the user out from all sessions (e.g., if they are logged in from multiple browsers or devices). To log out only from the current session, add the query parameter all_session=false (i.e., /logout?all_session=false).
Gradio’s built-in authentication provides a straightforward and basic layer of access control but does not offer robust security features for applications that require stringent access controls (e.g., multi-factor authentication, rate limiting, or automatic lockout policies).
For authentication to work properly, third-party cookies must be enabled in your browser. This is not the case by default for Safari or Chrome Incognito Mode.
OAuth with Hugging Face
Gradio natively supports OAuth login via Hugging Face. This allows you to easily add a “Sign in with Hugging Face” button to your demo, which gives you access to the user’s HF username and other profile information.
Setting up OAuth
To enable OAuth, you must set hf_oauth: true as a Space metadata in your README.md file. This registers your Space as an OAuth application on Hugging Face.
---
title: My Gradio App
emoji: 🚀
colorFrom: blue
colorTo: green
sdk: gradio
sdk_version: 4.0.0
app_file: app.py
hf_oauth: true
---
Next, use gr.LoginButton to add a login button to your Gradio app:
import gradio as gr
def greet(profile: gr.OAuthProfile | None):
if profile is None:
return "I don't know you."
return f"Hello {profile.name}"
with gr.Blocks() as demo:
gr.LoginButton()
m = gr.Markdown()
demo.load(greet, inputs=None, outputs=m)
demo.launch()
Accessing user profile
Once a user is logged in, you can retrieve their profile by adding a parameter of type gr.OAuthProfile to any Gradio function. The user profile will be automatically injected:
import gradio as gr
def show_profile(profile: gr.OAuthProfile | None):
if profile is None:
return "Please log in"
return f"""\n - Name: {profile.name}
- Username: {profile.username}
- Profile URL: {profile.profile}
"""
with gr.Blocks() as demo:
gr.LoginButton()
info = gr.Markdown()
demo.load(show_profile, None, info)
demo.launch()
Accessing user token
If you want to perform actions on behalf of the user (e.g., list user’s private repos, create repo, etc.), you can retrieve the user token by adding a parameter of type gr.OAuthToken:
import gradio as gr
from huggingface_hub import whoami
def list_organizations(oauth_token: gr.OAuthToken | None):
if oauth_token is None:
return "Please log in to list organizations."
org_names = [org["name"] for org in whoami(oauth_token.token)["orgs"]]
return f"You belong to: {', '.join(org_names)}"
with gr.Blocks() as demo:
gr.LoginButton()
m = gr.Markdown()
demo.load(list_organizations, inputs=None, outputs=m)
demo.launch()
You must define which scopes you will use in your Space metadata. See the Hugging Face documentation for more details on available scopes.
Local development with OAuth
OAuth features are only available when your app runs in a Space. However, you can test OAuth features locally by logging in to Hugging Face on your machine:
Or set the HF_TOKEN environment variable with one of your access tokens. You can generate a new token in your settings page.
Adding a gr.LoginButton does not restrict users from using your app. Users who have not logged in with Hugging Face can still access and run events in your Gradio app - the difference is that the gr.OAuthProfile or gr.OAuthToken will be None in the corresponding functions.
OAuth with external providers
It is also possible to authenticate with external OAuth providers (e.g., Google OAuth) in your Gradio apps. To do this, you must first mount your Gradio app within a FastAPI app.
Authentication dependency
You must write an authentication function that gets the user’s username from the OAuth provider and returns it. This function should be passed to the auth_dependency parameter in gr.mount_gradio_app.
The function should:
- Accept a single parameter: the FastAPI
Request
- Return either a string (representing a user’s username) or
None
- If a string is returned, the user will be able to access the Gradio app
- If
None is returned, access will be denied
Simple example
Here’s a simplistic example:
from fastapi import FastAPI, Request
import gradio as gr
import uvicorn
app = FastAPI()
def get_user(request: Request):
return request.headers.get("user")
def greet(name):
return f"Hello {name}!"
demo = gr.Interface(greet, "textbox", "textbox")
app = gr.mount_gradio_app(app, demo, path="/demo", auth_dependency=get_user)
if __name__ == '__main__':
uvicorn.run(app)
Google OAuth example
Here’s a more complete example showing how to add Google OAuth to a Gradio app:
import os
from authlib.integrations.starlette_client import OAuth, OAuthError
from fastapi import FastAPI, Depends, Request
from starlette.config import Config
from starlette.responses import RedirectResponse
from starlette.middleware.sessions import SessionMiddleware
import uvicorn
import gradio as gr
app = FastAPI()
# Replace these with your own OAuth settings
GOOGLE_CLIENT_ID = "..."
GOOGLE_CLIENT_SECRET = "..."
SECRET_KEY = "..."
config_data = {
'GOOGLE_CLIENT_ID': GOOGLE_CLIENT_ID,
'GOOGLE_CLIENT_SECRET': GOOGLE_CLIENT_SECRET
}
starlette_config = Config(environ=config_data)
oauth = OAuth(starlette_config)
oauth.register(
name='google',
server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
client_kwargs={'scope': 'openid email profile'},
)
app.add_middleware(SessionMiddleware, secret_key=SECRET_KEY)
# Dependency to get the current user
def get_user(request: Request):
user = request.session.get('user')
if user:
return user['name']
return None
@app.get('/')
def public(user: dict = Depends(get_user)):
if user:
return RedirectResponse(url='/gradio')
else:
return RedirectResponse(url='/login-demo')
@app.route('/logout')
async def logout(request: Request):
request.session.pop('user', None)
return RedirectResponse(url='/')
@app.route('/login')
async def login(request: Request):
redirect_uri = request.url_for('auth')
return await oauth.google.authorize_redirect(request, redirect_uri)
@app.route('/auth')
async def auth(request: Request):
try:
access_token = await oauth.google.authorize_access_token(request)
except OAuthError:
return RedirectResponse(url='/')
request.session['user'] = dict(access_token)["userinfo"]
return RedirectResponse(url='/')
with gr.Blocks() as login_demo:
gr.Button("Login", link="/login")
app = gr.mount_gradio_app(app, login_demo, path="/login-demo")
def greet(request: gr.Request):
return f"Welcome to Gradio, {request.username}"
with gr.Blocks() as main_demo:
m = gr.Markdown("Welcome to Gradio!")
gr.Button("Logout", link="/logout")
main_demo.load(greet, None, m)
app = gr.mount_gradio_app(app, main_demo, path="/gradio", auth_dependency=get_user)
if __name__ == '__main__':
uvicorn.run(app)
In this example, there are two separate Gradio apps:
- A login demo that displays a login button (accessible to any user)
- The main demo that is only accessible to logged-in users