Source code for litestar_oauth.providers.google

"""Google OAuth2 provider implementation."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from litestar_oauth.base import BaseOAuthProvider

if TYPE_CHECKING:
    from litestar_oauth.types import OAuthUserInfo


[docs] class GoogleOAuthProvider(BaseOAuthProvider): """Google OAuth2 provider with OpenID Connect support. Implements OAuth2 authentication flow for Google accounts. Supports OpenID Connect (OIDC) for enhanced authentication. Default scopes: - openid: Required for OIDC - email: Access user email - profile: Access user profile info User Info Mapping: - oauth_id: Google user ID (sub claim) - email: User email address - email_verified: Email verification status - username: Not provided by Google (uses email) - first_name: Given name - last_name: Family name - avatar_url: Profile picture URL - profile_url: Not provided by Google Args: client_id: Google OAuth client ID. client_secret: Google OAuth client secret. scope: Optional custom scopes. Defaults to ["openid", "email", "profile"]. """ @property def provider_name(self) -> str: """Return provider identifier. Returns: Provider name 'google'. """ return "google" @property def authorize_url(self) -> str: """Return Google authorization endpoint. Returns: Google OAuth authorization URL. """ return "https://accounts.google.com/o/oauth2/v2/auth" @property def token_url(self) -> str: """Return Google token exchange endpoint. Returns: Google OAuth token URL. """ return "https://oauth2.googleapis.com/token" @property def user_info_url(self) -> str: """Return Google user info endpoint. Returns: Google UserInfo endpoint URL. """ return "https://www.googleapis.com/oauth2/v3/userinfo" def _default_scope(self) -> list[str]: """Return default scopes for Google OAuth. Returns: List of default OAuth scopes. """ return ["openid", "email", "profile"]
[docs] async def get_user_info( self, access_token: str, **kwargs: Any, ) -> OAuthUserInfo: """Fetch and normalize Google user information. Retrieves user profile from Google UserInfo endpoint and normalizes it to OAuthUserInfo format. If an id_token is available from the token response, it can be used to verify claims. Args: access_token: Google OAuth access token. Returns: Normalized user information. Raises: ImportError: If httpx is not installed. Exception: If user info fetch fails. """ try: import httpx except ImportError as e: msg = "httpx is required for Google OAuth. Install it with: pip install httpx" raise ImportError(msg) from e from litestar_oauth.types import OAuthUserInfo headers = { "Authorization": f"Bearer {access_token}", } async with httpx.AsyncClient() as client: response = await client.get(self.user_info_url, headers=headers) response.raise_for_status() user_data = response.json() return OAuthUserInfo( provider=self.provider_name, oauth_id=user_data.get("sub", ""), email=user_data.get("email", ""), email_verified=user_data.get("email_verified", False), username=user_data.get("email", ""), # Google doesn't provide username first_name=user_data.get("given_name", ""), last_name=user_data.get("family_name", ""), avatar_url=user_data.get("picture", ""), profile_url="", # Google doesn't provide profile URL raw_data=user_data, )