EasyReasy.Auth.Google 1.0.0

dotnet add package EasyReasy.Auth.Google --version 1.0.0
                    
NuGet\Install-Package EasyReasy.Auth.Google -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EasyReasy.Auth.Google" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EasyReasy.Auth.Google" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="EasyReasy.Auth.Google" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EasyReasy.Auth.Google --version 1.0.0
                    
#r "nuget: EasyReasy.Auth.Google, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EasyReasy.Auth.Google@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EasyReasy.Auth.Google&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=EasyReasy.Auth.Google&version=1.0.0
                    
Install as a Cake Tool

EasyReasy.Auth.Google

Google Sign-In integration for the EasyReasy.Auth JWT authentication pipeline. Validates Google ID tokens and lets your application issue the same JWTs (and optional refresh tokens) as any other auth method.

Quick Start

1. Install

dotnet add package EasyReasy.Auth.Google

2. Implement IGoogleAuthHandler

This is where you decide what happens after a Google user is verified - look them up, create them, assign claims and roles, and build the JWT:

public class MyGoogleAuthHandler : IGoogleAuthHandler
{
    private readonly IUserRepository _users;

    public MyGoogleAuthHandler(IUserRepository users)
    {
        _users = users;
    }

    public async Task<AuthResponse?> HandleGoogleUserAsync(
        GoogleUserInfo userInfo,
        IJwtTokenService jwtTokenService,
        IRefreshTokenService? refreshTokenService,
        HttpContext? httpContext)
    {
        User user = await _users.FindOrCreateByGoogleSubjectAsync(
            userInfo.Subject, userInfo.Email, userInfo.Name);

        DateTime expiresAt = DateTime.UtcNow.AddHours(1);
        string token = jwtTokenService.CreateToken(
            subject: user.Id.ToString(),
            authType: "user",
            additionalClaims: [],
            roles: user.Roles,
            expiresAt: expiresAt);

        string? refreshToken = null;
        if (refreshTokenService != null)
        {
            refreshToken = await refreshTokenService.CreateRefreshTokenAsync(
                user.Id.ToString(), "user", null, null);
        }

        return new AuthResponse(token, expiresAt.ToString("o"), refreshToken);
    }
}

3. Register Services

// In Program.cs
builder.Services.AddEasyReasyAuth(jwtSecret);
builder.Services.AddEasyReasyGoogleAuth(googleClientId: "your-client-id.apps.googleusercontent.com");
builder.Services.AddScoped<IGoogleAuthHandler, MyGoogleAuthHandler>();

WebApplication app = builder.Build();

app.UseEasyReasyAuth();
app.AddGoogleAuthEndpoint();   // POST /api/auth/google
app.AddAuthEndpoints();        // the built-in EasyReasy.Auth endpoints (login, refresh, logout)

Flow

  1. Frontend uses Google's JavaScript SDK - user consents - frontend gets a Google ID token
  2. Frontend sends POST /api/auth/google with { "idToken": "..." }
  3. Library validates the ID token against Google's public keys
  4. Library enforces the hosted-domain allowlist and email-verification policy, then extracts GoogleUserInfo (subject, email, email-verified, name, picture URL)
  5. Library calls your IGoogleAuthHandler.HandleGoogleUserAsync
  6. You look up or create the user, issue a JWT via IJwtTokenService, optionally create a refresh token
  7. AuthResponse (token, expiration, optional refresh token) is returned to the frontend

Configuration

Restrict to Google Workspace Domains

builder.Services.AddEasyReasyGoogleAuth(
    googleClientId: "your-client-id.apps.googleusercontent.com",
    allowedHostedDomains: new[] { "yourcompany.com" });

When allowedHostedDomains is set, only users whose Google account belongs to one of those domains will be accepted. All other tokens are rejected. Domain matching is case-insensitive.

Email Verification

By default, accounts whose email address is not verified by Google (the token's email_verified claim is false) are rejected, matching Google's guidance that an unverified email must not be trusted as an identifier. If your application does not rely on the email address for identity, opt out:

builder.Services.AddEasyReasyGoogleAuth(
    googleClientId: "your-client-id.apps.googleusercontent.com",
    requireVerifiedEmail: false);

Either way, the verification state is exposed on GoogleUserInfo.EmailVerified so your IGoogleAuthHandler can make its own decision.

Endpoint Behavior

AddGoogleAuthEndpoint maps POST /api/auth/google with the same hardening as the built-in EasyReasy.Auth endpoints:

  • It is anonymous, so it stays reachable even when the application applies a global authorization policy.
  • It sets Cache-Control: no-store, so the issued token is never cached by browsers or proxies.

Audit Logging

Google sign-in flows into the same audit pipeline as every other EasyReasy.Auth event. If you register an IAuthAuditLogger (see the EasyReasy.Auth README, "Security Audit Logging"), the endpoint invokes OnExternalAuthAsync after every attempt — success or failure — before the response is written:

public class MyAuditLogger : IAuthAuditLogger
{
    private readonly ILogger<MyAuditLogger> _logger;

    public MyAuditLogger(ILogger<MyAuditLogger> logger) { _logger = logger; }

    public Task OnExternalAuthAsync(HttpContext ctx, ExternalAuthResult result)
    {
        _logger.LogInformation(
            "auth.external {Provider} {Outcome} subject={Subject} reason={Reason} ip={Ip}",
            result.Provider,                                  // "google"
            result.Success ? "success" : "failure",
            result.AttemptedSubject,
            result.FailureReason,
            ctx.Connection.RemoteIpAddress);
        return Task.CompletedTask;
    }
}

The ExternalAuthResult.FailureReason is InvalidToken when the Google ID token fails validation (bad signature, expiry, audience mismatch, a disallowed hosted domain, or an unverified email) and Rejected when your IGoogleAuthHandler returns null to decline an otherwise-valid identity. As with the other result types, log the metadata shown above — never the whole result, because on success it embeds the issued bearer token.

Models

GoogleUserInfo

Property Type Description
Subject string (required) Google's stable unique user ID (the sub claim)
Email string (required) The user's email address
EmailVerified bool (required) Whether Google has verified the user owns this email (the email_verified claim)
Name string? Display name, or null
PictureUrl string? Profile picture URL, or null

GoogleAuthRequest

Property Type Description
IdToken string The Google ID token from the frontend

Follows the standard EasyReasy serialization pattern: ToJson(), FromJson(string), ToString().

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 217 6/16/2026