Skip to main content
Version: MyBestDealNow

Google Login

Author(s)

  • Bishwanath Jana
  • Ayan Ghosh

Last Updated Date

2025-08-11


SRS References

  • 2.1.2 (External Authentication)

Version History

VersionDateChangesAuthor
1.02025-08-11Initial draft for Google LoginBishwanath Jana
2.02025-08-12Initial draft for Google LoginBishwanath Jana, Ayan Ghosh

Feature Overview

Objective:
Enable users to authenticate via Google using the ID token validation flow. The client obtains a Google ID token through Google OAuth and sends it to IAMService. IAMService validates the token through multiple security checks, verifies the user exists in our system, then issues an access token (returned in response body) and refresh token (set as HttpOnly cookie). This implementation follows a secure validation process that ensures only legitimate, existing users can authenticate.

Scope:
Backend authentication endpoint with comprehensive token validation. New login endpoint in IAMService that validates Google ID tokens and authenticates existing users only. No automatic user creation. Reuse existing JWT issuance and refresh-cookie logic. Optional domain restriction (Google Workspace).

Key Security Features:

  • Multi-step token validation (signature, audience, issuer, expiration, email verification)
  • Existing user validation (no automatic account creation)
  • Secure token distribution: Access token in response body, Refresh token in HttpOnly cookies
  • Comprehensive error handling and rejection of invalid requests

Dependencies:

  • Google Identity Platform (ID token issuance on the client)
  • NuGet: Google.Apis.Auth (ID token validation)
  • IAMService existing auth components: IAuthHelper, CookieHelper, DeviceTypeIdentifier, LoginResponse, MbdnStatusCode
  • Configuration keys: Google:ClientId (required), Google:HostedDomain (optional)

Requirements

  1. Provide a new POST /google-login endpoint (IAMService.AuthController) with AllowAnonymous.
  2. Accept body: { idToken: string (required), userType?: UserType }.
  3. Validate ID token using GoogleJsonWebSignature.ValidateAsync with Audience = Google:ClientId; enforce issuer and expiration.
  4. Token Validation Process:
    • Verify token signature and structure
    • Check aud (audience) claim matches configured Google:ClientId
    • Check iss (issuer) claim is from Google (accounts.google.com or https://accounts.google.com)
    • Check exp (expiration) claim to ensure token is not expired
    • Require email_verified = true in payload
    • Optionally enforce Google:HostedDomain match when configured
  5. User Lookup and Validation:
    • Find existing user by email from the validated token payload
    • If user does not exist in the system, reject the request with appropriate error message
    • Do not create new users automatically during Google login process
  6. Issue access token and a new refresh token for validated existing users only.
  7. Token Response Strategy:
    • Return access token in the response body as part of LoginResponse
    • Set refresh token via HttpOnly cookie using CookieHelper
    • Do not include refresh token in response body for security
  8. Return the standard LoginResponse payload with access token on successful authentication.
  9. Error Handling:
    • Invalid token → Return 400 Bad Request
    • Token validation failure (aud/iss/exp/email_verified) → Return 400 Bad Request
    • User not found → Return 400 Bad Request with "User does not exist" message
    • Server errors → Return 500 Internal Server Error
  10. Add audit logging and apply existing rate limiting to this endpoint.
  11. Add configuration keys: Google:ClientId (required), Google:HostedDomain (optional).
  12. Non-functional: enforce security validations, maintain performance comparable to other login calls, provide observability (metrics/logs), and preserve backward compatibility.

Detailed Authentication Flow

Based on the flowchart implementation, the Google authentication follows these specific steps:

Phase 1: Frontend Google OAuth

  • User clicks 'Login with Google' on Frontend
  • Frontend initiates Google OAuth with GOOGLE_CLIENT_ID & GOOGLE_CLIENT_SECRET
  • Google OAuth authenticates user and returns Tokens + Profile to Frontend

Phase 2: Token Transmission

  • Frontend sends IdToken + UserType to Backend via POST /google-login

Phase 3: Backend Validation

Step 1: Token Validation

Backend validates IdToken with GoogleJsonWebSignature.ValidateAsync
├─ Valid Token → Continue to Claims Check
└─ Invalid Token → Return 400 Bad Request

Step 2: Claims Verification

Check Claims:
├─ Verify 'aud' (audience) matches configured Google:ClientId
├─ Verify 'iss' (issuer) is from Google
├─ Verify 'exp' (expiration) - token not expired
└─ Verify 'email_verified' = true

├─ All Valid → Continue to User Lookup
└─ Any Invalid → Return 400 Bad Request

Step 3: User Existence Check

Find user by email:
├─ User Found → Issue Tokens
└─ User Not Found → Return 400 Bad Request "User does not exist"

Step 4: Token Issuance & Response

Issue AccessToken & RefreshToken:
├─ Return AccessToken in LoginResponse body
├─ Set RefreshToken in HttpOnly Cookie
└─ Frontend receives AccessToken in response, RefreshToken stored securely in cookie

Design Specifications

This section details the backend contract and integration points. UI is out of scope.

  • UI/UX Design:
    N/A (Backend-only feature)

  • Data Models:
    External identity model and request DTO used by the endpoint.

    // Request DTO
    public sealed class GoogleLoginRequest
    {
    public string IdToken { get; set; } = default!;
    public UserType? UserType { get; set; } // Optional; default decided by server policy
    }

    // External identity descriptor
    public sealed class ExternalIdentity
    {
    public string Provider { get; set; } = "Google";
    public string ProviderUserId { get; set; } = default!; // Google "sub"
    public string Email { get; set; } = default!;
    public string? Name { get; set; }
    }
  • API Interfaces:
    Endpoint for Google ID token exchange.

    EndpointMethodParametersResponseResponse Status Codes
    /google-loginPOSTBody: idToken (required, string), userType (optional, enum)LoginResponse200, 400, 401, 500
  • Third-Party Integrations:

    • Google Identity Platform (ID Token JWTs)
    • NuGet: Google.Apis.Auth (token validation)
  • Workflow:

    1. User Initiates Login: User clicks 'Login with Google' on Frontend
    2. Google OAuth Setup: Frontend sends GOOGLE_CLIENT_ID & GOOGLE_CLIENT_SECRET to Google OAuth
    3. Google Authentication: Google OAuth authenticates user and returns Tokens + Profile to Frontend
    4. Token Transmission: Frontend sends IdToken + UserType to Backend
    5. Token Validation: Backend validates IdToken with GoogleJsonWebSignature.ValidateAsync
    6. Validation Decision:
      • If token is invalid → Reject and return Bad Request
      • If token is valid → Proceed to claims verification
    7. Claims Verification: Check Claims:
      • Verify aud (audience)
      • Verify iss (issuer)
      • Verify exp (expiration)
      • Verify email_verified = true
    8. Claims Decision:
      • If any claim is invalid → Reject and return Bad Request
      • If all claims are valid → Proceed to user lookup
    9. User Lookup: Find user by email in the system
    10. User Existence Decision:
      • If user not found → Reject and return Bad Request with "User does not exist" message
      • If user found → Issue tokens
    11. Token Issuance: Issue AccessToken & RefreshToken
    12. Token Response:
      • Return AccessToken in response body (LoginResponse)
      • Set RefreshToken as HttpOnly cookie
      • Frontend stores AccessToken from response body for API calls

    Google login flow


Development Tasks & Estimates

NoTask NameEstimate (Hours)DependenciesNotes
1Add NuGet Google.Apis.Auth to IAMService0.5NuGet feedRestore/build
2Add config keys (ClientId, HostedDomain)0.5App settingsAll envs
3Add DTOs and helper signatures1.0ContractLibraryRequest/ExternalIdentity
4Implement comprehensive token validation logic3.0Google libaud/iss/exp/email_verified
5Implement AuthController /google-login endpoint2.0Validation logicRequest handling + error mapping
6Implement user lookup and existence validation2.0DALEmail-based user lookup
7Implement token issuance for existing users only2.0Auth helpersNo user creation logic
8Tests (unit + integration)2.5Test frameworkMock Google validate + all flows
Frontend Tasks
9Create google login service function2.0
10Implement google login profile callback2.0
11Create google login button in login page and implement google login2.0
Total19.5

Testing & Quality Assurance

  • Unit Tests:

    • Valid Flow: Valid token + existing user → success; access token in response body and refresh token cookie set
    • Token Validation Failures:
      • Invalid token signature → 400 Bad Request
      • Wrong audience (aud) → 400 Bad Request
      • Wrong issuer (iss) → 400 Bad Request
      • Expired token (exp) → 400 Bad Request
      • Email not verified (email_verified = false) → 400 Bad Request
    • User Validation:
      • Valid token + user not found by email → 400 Bad Request with "User does not exist"
      • Valid token + existing user → successful authentication with access token in body
    • Domain Restrictions: Hosted domain mismatch (when configured) → 400 Bad Request
  • Integration Tests:

    • End-to-end call to /google-login with mocked Google validator, verify LoginResponse and cookie flags across environments.
    • Verify refresh token rotation behavior.
    • Test complete authentication flow from frontend Google OAuth to backend token validation.
  • Acceptance Criteria:

    • Given a valid Google ID token for an existing user, API returns 200 with LoginResponse containing access token and sets refresh token as HttpOnly cookie.
    • Given an invalid token (any validation failure), API returns 400 Bad Request and does not set cookie or return access token.
    • Given a valid token for non-existing user, API returns 400 Bad Request with "User does not exist" message.
    • When HostedDomain is configured and mismatched, request is rejected with 400 Bad Request.
    • All token validation steps (aud, iss, exp, email_verified) are enforced correctly.
    • Access token is only returned in response body, never in cookies.
    • Refresh token is only set as HttpOnly cookie, never in response body.
  • Testing Tools:

    • xUnit/NUnit (unit tests), Moq/NSubstitute, Postman/REST Client, Application Insights/Serilog for logs

Deployment Considerations

  • Configuration Changes:

    • Add to IAMService appsettings: Google:ClientId (required), Google:HostedDomain (optional)
    • Configure secrets per environment; do not store secrets in repo
    • No feature flag required
  • Rollout Plan:

    • Deploy IAMService after config keys are present
    • Smoke-test /google-login in each environment
    • Monitor failures; rollback by reverting the service version if needed
  • Optional Schema Change:

    • If not already present, consider an ExternalLogin table to store provider links:
      • Columns: Id (PK), UserId (FK), Provider (nvarchar), ProviderUserId (nvarchar), CreatedAt
      • Unique index on (Provider, ProviderUserId)

Risks & Mitigations

RiskImpactLikelihoodMitigation Strategy
Invalid token acceptanceHighLowMulti-step validation: signature, aud, iss, exp, email_verified checks
Token replay attacksHighLowEnforce expiration validation and token uniqueness
Unauthorized user creationHighVery LowRemoved: Only existing users can authenticate via Google login
Account enumeration via loginMediumLowGeneric error messages; rate limiting; audit logging
Domain policy bypassMediumLowEnforce HostedDomain when configured; test negative cases
Cookie misconfigurationMediumMediumValidate HttpOnly/Secure/SameSite per environment; integration tests
Rate limiting gapsMediumMediumApply existing auth rate-limits; monitor failed attempts
User not found attacksLowMediumGeneric error handling; avoid revealing system user information

Review & Approval

  • Reviewer:
    Ayon Das

  • Approval Date:
    2025-08-12


Notes

  • Frontend/UI integration is out of scope here; clients should use Google Identity Services to obtain ID tokens.
  • Reuse existing JWT and refresh token flow to minimize client-side changes.
  • Consider adding metrics for attempts/success/failure to improve observability.