Skip to content

Add OAuth authentication tutorial #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
CLAUDE.md
.sesskey
.plash
.specstory/
Expand Down
292 changes: 292 additions & 0 deletions nbs/how_to/02_user_authentication.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Implement OAuth Authentication\n",
"\n",
"> How to add OAuth authentication to your Plash app"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This guide shows you how to add OAuth authentication to your Plash app. We will be using Google OAuth where users can log in with their existing Google accounts."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step by step tutorial\n",
"\n",
"In this tutorial, you'll learn how to use environment variables in your Plash app.\n",
"\n",
"**Prerequisites:**\n",
"\n",
"* A registered account at https://pla.sh\n",
"* The Plash CLI installed (run `pip install plash-cli` if needed)\n",
"* Logged in via the CLI (run `plash_login` if needed)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"from plash_cli._bash_magic import *\n",
"import tempfile\n",
"temp_dir = tempfile.TemporaryDirectory()\n",
"td = temp_dir.name"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"%%bash\n",
"#| hide\n",
"cd $`td`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 1: Set up Google OAuth credentials\n",
"\n",
"Create OAuth credentials in the Google Cloud Console:\n",
"\n",
"1. Go to [Google Cloud Console](https://console.cloud.google.com/)\n",
"2. Create a new project or select an existing one\n",
"3. Go to \"APIs & Services\" > \"Credentials\"\n",
"4. Click \"Create Credentials\" > \"OAuth client ID\"\n",
"5. Select \"Web application\" as the application type\n",
"6. Add `https://your-app-id.pla.sh/redirect` to the authorized redirect URIs\n",
"7. Save your Client ID and Client Secret"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 2: Create a project directory"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"%%bash\n",
"mkdir -p oauth-auth-app\n",
"cd oauth-auth-app"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%writefile .plash\n",
"export PLASH_APP_ID='oauth-example-app'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 3: Create the environment variables file"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%writefile plash.env\n",
"export GOOGLE_CLIENT_ID=\"your-google-client-id\"\n",
"export GOOGLE_CLIENT_SECRET=\"your-google-client-secret\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 4: Create the main application file"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%writefile main.py\n",
"from fasthtml.common import *\n",
"from fasthtml.oauth import OAuth, GoogleAppClient\n",
"import os\n",
"\n",
"# Initialize the app\n",
"app, rt = fast_app()\n",
"\n",
"# Create Google OAuth client\n",
"client = GoogleAppClient(\n",
" os.environ.get(\"GOOGLE_CLIENT_ID\"),\n",
" os.environ.get(\"GOOGLE_CLIENT_SECRET\")\n",
")\n",
"\n",
"# Define authentication class\n",
"class Auth(OAuth):\n",
" def get_auth(self, info, ident, session, state):\n",
" email = info.email or ''\n",
" if info.email_verified:\n",
" session['user'] = {'name': info.name}\n",
" return RedirectResponse('/', status_code=303)\n",
"\n",
"# Initialize OAuth\n",
"oauth = Auth(app, client)\n",
"\n",
"# Home route\n",
"@rt\n",
"def index(req, sess):\n",
" # Check if user is logged in\n",
" user = sess.get(\"user\") if sess else None\n",
" \n",
" style = \"font-family: system-ui; max-width: 600px; margin: 0 auto; padding: 2rem;\"\n",
" \n",
" if user:\n",
" # Logged in view\n",
" return Div(\n",
" H1(f\"Hello, {user['name']}!\"),\n",
" P(\"You are logged in with Google.\"),\n",
" A(\"Logout\", href=\"/logout\"),\n",
" )\n",
" else:\n",
" # Login page\n",
" return Div(\n",
" H1(\"OAuth Example\"),\n",
" P(\"Click below to log in:\"),\n",
" A(\"Login with Google\", href=oauth.login_link(req)),\n",
" )\n",
"\n",
"# Login route\n",
"@rt\n",
"def login(req):\n",
" style = \"font-family: system-ui; max-width: 600px; margin: 0 auto; padding: 2rem;\"\n",
" return Div(\n",
" H1(\"Login\"),\n",
" A(\"Login with Google\", href=oauth.login_link(req)),\n",
" style=style\n",
" )\n",
"\n",
"serve()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 5: Create the requirements file"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%writefile requirements.txt\n",
"python-fasthtml>=0.7.0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 6: Deploy your application"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Initializing deployment...\n",
"✅ Upload complete! Your app is currently being built.\n",
"It will be live at https://oauth-example-app.pla.sh\n",
"\n"
]
}
],
"source": [
"%%bash\n",
"#| output: false\n",
"plash_deploy"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That's it! Your app now has Google OAuth authentication. When users visit, they'll see a login button that redirects them to Google for authentication.\n",
"\n",
"::: {.callout-tip}\n",
"For more OAuth features, check out the [FastHTML OAuth documentation](https://fastht.ml/docs/explains/oauth.html).\n",
":::\n",
"\n",
"**🎉 Complete: Environment Variables Tutorial**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "python3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading