OAuth Client setting:
Social Login Key setting:
gradio web app code:
import uvicorn
from fastapi import FastAPI, Depends
from starlette.responses import RedirectResponse
from starlette.middleware.sessions import SessionMiddleware
from authlib.integrations.starlette_client import OAuth, OAuthError
from fastapi import Request
import os
import json
from starlette.config import Config
import gradio as gr
import logging
import sys
from dotenv import load_dotenv
load_dotenv(".env")
app = FastAPI()
SECRET_KEY = "SECRET_KEY"
app.add_middleware(SessionMiddleware, secret_key=SECRET_KEY)
oauth = OAuth()
### frappe
oauth.register(
name='custom',
client_id=os.environ.get('FRAPPE_CLIENT_ID'),
client_secret=os.environ.get('FRAPPE_CLIENT_SECRET'),
access_token_url='https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.get_token',
# access_token_params=None,
authorize_url='https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.authorize',
# authorize_params=None,
api_base_url='https://yiouyou.frappe.cloud',
client_kwargs={
'scope': 'openid',
'redirect_uri': 'http://127.0.0.1:8000/auth'
},
userinfo_endpoint='https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.openid_profile',
# redirect_uri='http://127.0.0.1:8000/api/method/frappe.integrations.oauth2_logins.login_via_frappe',
)
custom = oauth.create_client('custom')
# Dependency to get the current user
def get_user(request: Request):
user = None
print('get_user.request.session', request.session)
if 'user' in request.session.keys():
if isinstance(request.session['user'], dict):
_user = request.session['user']
elif isinstance(request.session['user'], str):
_user = json.loads(request.session['user'])
# print("\n\nuser",_user)
if 'name' in _user.keys():
user = _user['name']
elif 'login' in _user.keys():
user = _user['login']
return user
@app.get('/')
def public(request: Request, user = Depends(get_user)):
root_url = gr.route_utils.get_root_url(request, "/", None)
if user:
return RedirectResponse(url=f'{root_url}/gradio/')
else:
return RedirectResponse(url=f'{root_url}/main/')
@app.get('/logout')
async def logout(request: Request):
request.session.pop('user', None)
return RedirectResponse(url='/')
@app.get('/login')
async def login(request: Request):
print('/login', request.session)
root_url = gr.route_utils.get_root_url(request, "/login", None)
redirect_uri = f"{root_url}/auth"
print("/login Redirecting to", redirect_uri)
return await custom.authorize_redirect(request, redirect_uri)
@app.get('/auth')
async def auth(request: Request):
print('/auth', request.session)
try:
access_token = await custom.authorize_access_token(request)
print('access_token', access_token)
except OAuthError:
print("Error getting access token", str(OAuthError))
return RedirectResponse(url='/')
user = access_token.get('userinfo')
print(user)
if user:
request.session['user'] = dict(user)
print("/auth Redirecting to /gradio")
return RedirectResponse(url='/gradio')
with gr.Blocks() as _main:
btn = gr.Button("Login")
_js_redirect = """
() => {
url = '/login' + window.location.search;
window.open(url, '_blank');
}
"""
btn.click(None, js=_js_redirect)
app = gr.mount_gradio_app(app, _main, path="/main")
def greet(request: gr.Request):
return f"Welcome, {request.username}"
with gr.Blocks() as _gradio:
m = gr.Markdown("Welcome to Gradio!")
_url = 'http://127.0.0.1:3000/'
iframe = f'<iframe src={_url} style="border:0;height:900px;width:100%;allow:microphone;">'
gr.HTML(iframe)
gr.Button("Logout", link="/logout")
_gradio.load(greet, None, m)
app = gr.mount_gradio_app(app, _gradio, path="/gradio", auth_dependency=get_user)
if __name__ == '__main__':
uvicorn.run(app, host='127.0.0.1', port=8000)
When open http://127.0.0.1:8000/main/ in browser, click the login button, it shows:
But after clicking the Allow button, it fails to open /gradio web content, but shows:
{"detail":"Not authenticated"}
I tryed my best to debug, but have no clue why it doesn’t work as expected. The error is like below:
(venv) PS E:\_Ai\free> python ttt1.py
INFO: Started server process [18124]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
get_user.request.session {'_state_custom_vSz7iDKyXolplT9pBrDc1vteAuRcVa': {'data': {'redirect_uri': 'http://127.0.0.1:8000/auth', 'nonce': 'ObhMxyg6xrt0IpachzuL', 'url': 'https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.authorize?response_type=code&client_id=1af911c5c4&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fauth&scope=openid&state=vSz7iDKyXolplT9pBrDc1vteAuRcVa&nonce=ObhMxyg6xrt0IpachzuL'}, 'exp': 1711996631.7465434}, '_state_custom_Uu6NEwh69WCbKCzhmZ8A48wHutsW4V': {'data': {'redirect_uri': 'http://127.0.0.1:8000/auth', 'nonce': 'EvzMzhJGwJwBXeP8d2KS', 'url': 'https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.authorize?response_type=code&client_id=1af911c5c4&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fauth&scope=openid&state=Uu6NEwh69WCbKCzhmZ8A48wHutsW4V&nonce=EvzMzhJGwJwBXeP8d2KS'}, 'exp': 1711996662.8727467}}
INFO: 127.0.0.1:58530 - "GET / HTTP/1.1" 307 Temporary Redirect
INFO: 127.0.0.1:58530 - "GET /main/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:58530 - "GET /main/assets/index-138adf03.css HTTP/1.1" 200 OK
INFO: 127.0.0.1:58531 - "GET /main/assets/index-10ead756.js HTTP/1.1" 200 OK
INFO: 127.0.0.1:58531 - "GET /main/assets/svelte/svelte.js HTTP/1.1" 200 OK
INFO: 127.0.0.1:58530 - "GET /main/assets/Index-7fdff9d2.js HTTP/1.1" 200 OK
INFO: 127.0.0.1:58531 - "GET /main/assets/Index-b2fdba73.css HTTP/1.1" 200 OK
INFO: 127.0.0.1:58530 - "GET /assets/index-138adf03.css HTTP/1.1" 404 Not Found
INFO: 127.0.0.1:58530 - "GET /main/info HTTP/1.1" 200 OK
INFO: 127.0.0.1:58530 - "GET /main/theme.css HTTP/1.1" 200 OK
INFO: 127.0.0.1:58531 - "GET /main/assets/Blocks-e8e682ce.js HTTP/1.1" 200 OK
INFO: 127.0.0.1:58536 - "GET /main/assets/Button-2a9911a9.css HTTP/1.1" 200 OK
INFO: 127.0.0.1:58537 - "GET /main/assets/Blocks-2b5ac0cf.css HTTP/1.1" 200 OK
INFO: 127.0.0.1:58538 - "GET /main/assets/Button-bd009e9a.js HTTP/1.1" 200 OK
INFO: 127.0.0.1:58538 - "GET /main/assets/Index-37392b60.js HTTP/1.1" 200 OK
INFO: 127.0.0.1:58531 - "GET /main/assets/Index-2abed479.css HTTP/1.1" 200 OK
INFO: 127.0.0.1:58537 - "GET /main/assets/Index-24a33ce1.js HTTP/1.1" 200 OK
INFO: 127.0.0.1:58537 - "GET /main/assets/api-logo-5346f193.svg HTTP/1.1" 200 OK
INFO: 127.0.0.1:58531 - "GET /main/assets/logo-3707f936.svg HTTP/1.1" 200 OK
/login {'_state_custom_vSz7iDKyXolplT9pBrDc1vteAuRcVa': {'data': {'redirect_uri': 'http://127.0.0.1:8000/auth', 'nonce': 'ObhMxyg6xrt0IpachzuL', 'url': 'https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.authorize?response_type=code&client_id=1af911c5c4&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fauth&scope=openid&state=vSz7iDKyXolplT9pBrDc1vteAuRcVa&nonce=ObhMxyg6xrt0IpachzuL'}, 'exp': 1711996631.7465434}, '_state_custom_Uu6NEwh69WCbKCzhmZ8A48wHutsW4V': {'data': {'redirect_uri': 'http://127.0.0.1:8000/auth', 'nonce': 'EvzMzhJGwJwBXeP8d2KS', 'url': 'https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.authorize?response_type=code&client_id=1af911c5c4&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fauth&scope=openid&state=Uu6NEwh69WCbKCzhmZ8A48wHutsW4V&nonce=EvzMzhJGwJwBXeP8d2KS'}, 'exp': 1711996662.8727467}}
/login Redirecting to http://127.0.0.1:8000/auth
INFO: 127.0.0.1:58531 - "GET /login HTTP/1.1" 302 Found
/auth {'_state_custom_vSz7iDKyXolplT9pBrDc1vteAuRcVa': {'data': {'redirect_uri': 'http://127.0.0.1:8000/auth', 'nonce': 'ObhMxyg6xrt0IpachzuL', 'url': 'https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.authorize?response_type=code&client_id=1af911c5c4&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fauth&scope=openid&state=vSz7iDKyXolplT9pBrDc1vteAuRcVa&nonce=ObhMxyg6xrt0IpachzuL'}, 'exp': 1711996631.7465434}, '_state_custom_Uu6NEwh69WCbKCzhmZ8A48wHutsW4V': {'data': {'redirect_uri': 'http://127.0.0.1:8000/auth', 'nonce': 'EvzMzhJGwJwBXeP8d2KS', 'url': 'https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.authorize?response_type=code&client_id=1af911c5c4&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fauth&scope=openid&state=Uu6NEwh69WCbKCzhmZ8A48wHutsW4V&nonce=EvzMzhJGwJwBXeP8d2KS'}, 'exp': 1711996662.8727467}, '_state_custom_jW0RNlW6m6tJ407aWTvBHoSUaIsUlG': {'data': {'redirect_uri': 'http://127.0.0.1:8000/auth', 'nonce': 'DZYLepwFdp7KOaq8U2GG', 'url': 'https://yiouyou.frappe.cloud/api/method/frappe.integrations.oauth2.authorize?response_type=code&client_id=1af911c5c4&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fauth&scope=openid&state=jW0RNlW6m6tJ407aWTvBHoSUaIsUlG&nonce=DZYLepwFdp7KOaq8U2GG'}, 'exp': 1712037232.0765035}}
access_token {'exception': 'frappe.exceptions.AuthenticationError', 'exc_type': 'AuthenticationError', 'exc': '["Traceback (most recent call last):\\n File \\"apps/frappe/frappe/app.py\\", line 97, in application\\n validate_auth()\\n File \\"apps/frappe/frappe/auth.py\\", line 587, in validate_auth\\n validate_auth_via_api_keys(authorization_header)\\n File \\"apps/frappe/frappe/auth.py\\", line 650, in validate_auth_via_api_keys\\n validate_api_key_secret(api_key, api_secret, authorization_source)\\n File \\"apps/frappe/frappe/auth.py\\", line 668, in validate_api_key_secret\\n raise frappe.AuthenticationError\\nfrappe.exceptions.AuthenticationError\\n"]'}
Error getting access token <class 'authlib.integrations.base_client.errors.OAuthError'>
INFO: 127.0.0.1:58531 - "GET /auth?code=fEea0oOPffpwnPSFFhKiuLLclwn58q&state=jW0RNlW6m6tJ407aWTvBHoSUaIsUlG HTTP/1.1" 307 Temporary Redirect
get_user.request.session {}
INFO: 127.0.0.1:58531 - "GET / HTTP/1.1" 307 Temporary Redirect
INFO: 127.0.0.1:58531 - "GET /main/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:58531 - "GET /assets/index-138adf03.css HTTP/1.1" 404 Not Found
INFO: 127.0.0.1:58531 - "GET /main/info HTTP/1.1" 200 OK
INFO: 127.0.0.1:58531 - "GET /main/theme.css HTTP/1.1" 200 OK
Among the log, the access_token is wrong with AuthenticationError:
access_token {
'exception': 'frappe.exceptions.AuthenticationError',
'exc_type': 'AuthenticationError',
'exc': '["Traceback (most recent call last):\\n File \\"apps/frappe/frappe/app.py\\", line 97, in application\\n validate_auth()\\n File \\"apps/frappe/frappe/auth.py\\", line 587, in validate_auth\\n validate_auth_via_api_keys(authorization_header)\\n File \\"apps/frappe/frappe/auth.py\\", line 650, in validate_auth_via_api_keys\\n validate_api_key_secret(api_key, api_secret, authorization_source)\\n File \\"apps/frappe/frappe/auth.py\\", line 668, in validate_api_key_secret\\n raise frappe.AuthenticationError\\nfrappe.exceptions.AuthenticationError\\n"]'}
Error getting access token <class 'authlib.integrations.base_client.errors.OAuthError'>
Anyone can help me with the problem, I’d like even to pay for the bedug solution.
Thanks a lot,
Zack