Browse Source

Add Google OAuth2 example (#4371)

Adds the Google OAuth2 example that I created
[here](https://github.com/zauberzeug/nicegui/discussions/4361)
Unfortunately, I'm not very skilled with readme's, so I used some images
and text where I could. I ask that you guys fix that (if you feel it's
necessary).
Let me know what you guys think.

---------

Co-authored-by: Rodja Trappe <rodja@zauberzeug.com>
Co-authored-by: Falko Schindler <falko@zauberzeug.com>
frankvp 2 months ago
parent
commit
729e714621
3 changed files with 54 additions and 0 deletions
  1. 52 0
      examples/google_oauth2/main.py
  2. 1 0
      examples/google_oauth2/requirements.txt
  3. 1 0
      website/examples.py

+ 52 - 0
examples/google_oauth2/main.py

@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+from typing import Optional
+
+from authlib.integrations.starlette_client import OAuth, OAuthError
+from fastapi import Request
+from starlette.responses import RedirectResponse
+
+from nicegui import app, ui
+
+# Get the credentials from the Google Cloud Console
+# https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid#get_your_google_api_client_id
+GOOGLE_CLIENT_ID = '...'
+GOOGLE_CLIENT_SECRET = '...'
+
+oauth = OAuth()
+oauth.register(
+    name='google',
+    server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
+    client_id=GOOGLE_CLIENT_ID,
+    client_secret=GOOGLE_CLIENT_SECRET,
+    client_kwargs={'scope': 'openid email profile'},
+)
+
+
+@app.get('/auth')
+async def google_oauth(request: Request) -> RedirectResponse:
+    try:
+        user_data = await oauth.google.authorize_access_token(request)
+    except OAuthError as e:
+        print(f'OAuth error: {e}')
+        return RedirectResponse('/')  # or return an error page/message
+    app.storage.user['user_data'] = user_data
+    return RedirectResponse('/')
+
+
+def logout() -> None:
+    del app.storage.user['user_data']
+    ui.navigate.to('/')
+
+
+@ui.page('/')
+async def main(request: Request) -> Optional[RedirectResponse]:
+    user_data = app.storage.user.get('user_data', None)
+    if user_data:
+        ui.label(f'Welcome {user_data.get("userinfo", {}).get("name", "")}!')
+        ui.button('Logout', on_click=logout)
+        return None
+    else:
+        url = request.url_for('google_oauth')
+        return await oauth.google.authorize_redirect(request, url)
+
+ui.run(host='localhost', storage_secret='random secret goes here')

+ 1 - 0
examples/google_oauth2/requirements.txt

@@ -0,0 +1 @@
+authlib

+ 1 - 0
website/examples.py

@@ -72,4 +72,5 @@ examples: List[Example] = [
     Example('OpenAI Assistant', "Using OpenAI's Assistant API with async/await"),
     Example('Redis Storage', 'Use Redis storage to share data across multiple instances behind a reverse proxy or load balancer'),
     Example('Google One-Tap Auth', 'Authenticate users via Google One-Tap'),
+    Example('Google OAuth2', 'Authenticate with Google OAuth2')
 ]