Google Cloud 가입 - 해외 결제 가능한 카드 필요
프로젝트 생성 - 처음 가입하면 My First Project라는 이름으로 생성되어 있음
혹은 그 버튼을 클릭해서 프로젝트 생성 - 생성 시 이름 변경 안 됨
좌측 최상단에 메뉴바 > API 및 서비스
사용자 인증 정보 > 사용자 인증 정보 만들기 > OAuth 클라이언트 ID
사용자 유형 외부
로 설정
우리는 사용자 메일을 읽어오니 OAuth로 인증해야 해요
사용 설정된 API 및 서비스 > API 및 서비스 사용 설정 > Gmail 검색 후 사용 설정
일단 애플리케이션 유형은 웹 애플리케이션으로 함
나중에 변경 가능한 것 같음
중요! 승인된 리디렉션 URI에 http://localhost:8080/
입력하기 (추후 코드에서 설명할 거임)
슬래시까지 정확하게 입력해야 함
Additional information에서 JSON 다운로드 후 credentials.json
으로 파일명 변경
왜인지는 모르겠지만 OAuth 동의 화면 > 게시 상태
에서 앱 게시
를 클릭해야 리디렉션이 됨
다음 코드 실행
디렉토리 구조
project_directory
┠ oauth_test.py
┗ credentials.json
모듈 설치
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
oauth_test.py
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = ["<https://www.googleapis.com/auth/gmail.readonly>"]
def main():
"""Shows basic usage of the Gmail API.
Lists the user's Gmail labels.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first time.
if os.path.exists("token.json"):
creds = Credentials.from_authorized_user_file("token.json", SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
# 여기서 포트를 8080으로 강제 지정
# 슬래시 입력 안 하면 400 redirect_uri_mismatch 에러 뜹니다.
flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
creds = flow.run_local_server(
port=8080, prompt="consent", access_type="offline"
)
# Save the credentials for the next run
with open("token.json", "w") as token:
token.write(creds.to_json())
try:
# Call the Gmail API
service = build("gmail", "v1", credentials=creds)
results = service.users().labels().list(userId="me").execute()
labels = results.get("labels", [])
if not labels:
print("No labels found.")
return
print("Labels:")
for label in labels:
print(label["name"])
except HttpError as error:
# TODO(developer) - Handle errors from gmail API.
print(f"An error occurred: {error}")
if __name__ == "__main__":
main()
코드 실행하면 Gmail로 로그인 창 뜨면서 로그인 됨!
뿌-듯
이후 터미널에 현재 있는 라벨 전부 출력됨
한 번 더 실행하면 token.json
에 인증 토큰이 담겨서 로그인 단계 건너뛰고 라벨만 긁어옵니다.
인증 토큰 노출 안 되게 잘 숨겨야겠죠?