From 1767cd58612e32e8323e717dc8dbaa6e3721bd89 Mon Sep 17 00:00:00 2001 From: imnyang Date: Mon, 23 Jun 2025 20:38:02 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20OAuth=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=20=EB=B0=8F=20=EB=AA=A8=EB=8D=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95,=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=B0=8F=20=EC=84=A4=EC=A0=95=20=EA=B3=BC=EC=A0=95=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20-=20Windows=EC=97=90=EC=84=9C=20storage=5Fstate=20?= =?UTF-8?q?=EC=9D=B4=EC=8A=88=EA=B0=80=20=EC=9D=BC=EC=96=B4=EB=82=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/llm/prompt/auth_list.py | 30 ++++++++++-------------------- lib/llm/prompt/fallback.py | 2 +- lib/utils/browser_use/model.py | 2 +- main.py | 5 +++-- setup.py | 6 +++--- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/lib/llm/prompt/auth_list.py b/lib/llm/prompt/auth_list.py index ad32f40..55a4bfb 100644 --- a/lib/llm/prompt/auth_list.py +++ b/lib/llm/prompt/auth_list.py @@ -1,12 +1,12 @@ +# @file purpose: This file contains the prompt for extracting a list of OAuth providers from a web page. # OAuth 리스트 추출용 프롬프트 (클릭하지 않고 단순 식별만) extract_oauth_list_prompt = f""" -🎯 목적: 주어진 초기 URL 내에서 **OAuth 로그인 URL**을 찾아 아래 형식의 JSON으로 정리합니다. +🎯 목적: 주어진 초기 URL 내에서 **OAuth 로그인 Provider**를 찾아 아래 형식의 JSON으로 정리합니다. 📌 작업 목표: -- Google, GitHub, Discord, Facebook, Apple 등 **OAuth 인증을 사용하는 외부 로그인 링크**를 모두 수집합니다. +- Google, GitHub, Discord, Facebook, Apple, Microsoft, Twitter, LinkedIn 등 **OAuth 인증을 사용하는 외부 로그인 링크**에서 Provider 이름만 모두 수집합니다. - 로그인 버튼, 링크 클릭 등을 통해 탐색을 진행할 수 있습니다. -- OAuth URL이 실제로 포함된 최종 리디렉션 URL 또는 팝업 주소를 캡처합니다. -- **같은 provider가 여러 번 나와도 가장 대표적인 URL 하나만 저장**합니다. +- **같은 provider가 여러 번 나와도 하나만 저장**합니다. 🛑 제한 사항: - ❌ 로그인 입력창이나 이메일/비밀번호 입력 방식은 제외합니다. @@ -15,8 +15,7 @@ extract_oauth_list_prompt = f""" 🔍 탐색 방법: 1. 초기 URL에 접속하여 **클라이언트용 로그인 페이지**로 진입합니다. 2. 페이지가 정상적으로 로드되었다고 가정합니다. -3. 'Continue with X', 'Continue with Google'... 등의 버튼이나 링크를 클릭합니다. -4. 버튼 클릭 시 리디렉션되거나 팝업이 열린다면 해당 주소를 확인합니다. +3. 'Continue with X', 'Continue with Google'... 등의 버튼이나 링크를 식별합니다. 🧾 출력 형식 (예시): @@ -24,25 +23,16 @@ extract_oauth_list_prompt = f""" ```json {{ "oauth_providers": [ - {{ - "provider": "Google", - "oauth_uri": "https://accounts.google.com/o/oauth2/v2/auth?client_id=..." - }}, - {{ - "provider": "GitHub", - "oauth_uri": "https://github.com/login/oauth/authorize?client_id=..." - }}, - {{ - "provider": "Discord", - "oauth_uri": "https://discord.com/oauth2/authorize?client_id=..." - }} + "Google", + "GitHub", + "Discord" ] }} ``` 📌 주의: - 결과가 없는 provider는 JSON에 포함하지 않아도 됩니다. - 정확한 provider 이름과 oauth_uri를 매칭해 주세요 + 결과가 없는 경우 빈 배열 `[]`로 반환합니다. + 정확한 provider 이름을 포함해 주세요. """ diff --git a/lib/llm/prompt/fallback.py b/lib/llm/prompt/fallback.py index 58b2889..b8ae199 100644 --- a/lib/llm/prompt/fallback.py +++ b/lib/llm/prompt/fallback.py @@ -74,7 +74,7 @@ extend_planner_system_message = f""" - **로그인 완료 후 authorize 등 버튼이 있으면 클릭** - GitHub같은 경우 Authorize 버튼이 뜨는데 오래걸릴 수 있음, 기다려야 할 수도 있음 - 만약 버튼을 눌러도 반응이 없을 경우 새로고침을 한번 해주세요. - - 로그인 실패 시에는 다음 SSO 버튼을 클릭합니다. + - **OAuth Flow가 완료되면 (callback URL 도달 또는 인증 완료) 즉시 작업 종료** 4. 로그인이 성공하면 모두 쿠키를 삭제하고 다음 SSO 버튼을 클릭합니다. 5. 다음 SSO 버튼으로 반복 진행 diff --git a/lib/utils/browser_use/model.py b/lib/utils/browser_use/model.py index 4d1078b..6a1178f 100644 --- a/lib/utils/browser_use/model.py +++ b/lib/utils/browser_use/model.py @@ -8,7 +8,7 @@ class OAuth(BaseModel): class OAuthList(BaseModel): - oauth_providers: List[OAuth] + oauth_providers: List[str] # 이제 문자열 배열로 변경 # 기존 모델 유지 (backward compatibility) diff --git a/main.py b/main.py index a990aa5..e531479 100644 --- a/main.py +++ b/main.py @@ -147,7 +147,8 @@ async def extract_oauth_list(url: str, skip_html_check: bool = False): raise ValueError("OAuth 리스트 추출 결과가 None입니다.") data = json.loads(final_result) - oauth_entries = [model.OAuth(**entry) for entry in data["oauth_providers"]] + oauth_providers = data["oauth_providers"] # 이제 문자열 배열 + oauth_entries = [model.OAuth(provider=provider) for provider in oauth_providers] await clean_resources(agent, session) return oauth_entries @@ -293,7 +294,7 @@ async def scan_one_url(url: str, skip_html_check: bool = False): if not file_exists: writer.writerow(["issuer", "provider", "oauth_uri", "login_tested"]) for entry in oauth_entries: - writer.writerow([url, entry.provider, entry.oauth_uri, "pending"]) + writer.writerow([url, entry.provider, "", "pending"]) # oauth_uri는 빈 문자열 # 2단계: 각 OAuth 제공자별로 개별 로그인 시도 for i, oauth_entry in enumerate(oauth_entries): diff --git a/setup.py b/setup.py index 646fc28..d54d458 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ def create_file_from_example(target: str, example: str) -> bool: with open(example, 'r', encoding='utf-8') as example_file, \ open(target, 'w', encoding='utf-8') as target_file: target_file.write(example_file.read()) - os.startfile(target) + #os.startfile(target) print(f"✅ {target} 파일이 {example}에서 생성되었습니다.") return True else: @@ -44,8 +44,8 @@ def setup_storage(): print("======================================================") print("👀 원하는 OAuth Providor를 직접 모두 로그인 한 후에 브라우저를 닫으면 설정이 완료됩니다.") os.system('uv run playwright open https://google.com/ --save-storage=./data/storage_state.json') - if os.path.exists('./data/storage_state.json'): - os.startfile('./data/storage_state.json') + #if os.path.exists('./data/storage_state.json'): + # os.startfile('./data/storage_state.json') print("✅ 쿠키와 로컬 스토리지 설정 완료.") print("💾 ./data/storage_state.json 파일이 생성되었습니다.") else: