Back to "Google Auth -palvelun lisääminen ilman ASP.NET-identiteettitietokantaa"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

ASP.NET Google Auth

Google Auth -palvelun lisääminen ilman ASP.NET-identiteettitietokantaa

Monday, 05 August 2024

Esitys

Halusin lisätä tähän appiin simpple-mekanismin, joka sallii liittymisen lisätä kommentteja (ja joitakin hallinnollisia tehtäviä )appille. Halusin käyttää Google Auth-järjestelmää tähän tarkoitukseenM SK3 En halunnut käyttää ASP:taMSC4NET-identiteettitietokantaa tähän tarkoituksiinMST5 Haluan pitää appin mahdollisimman yksinkertaisena niin kauan kuin mahdollistaMSV6

Tietokannat ovat kaikkien sovellusten tehokas osatekijä, mutta ne lisäävät myös monimutkaisuutta.

Askeleet

Ensinnäkin Google Auth on otettava käyttöön Google Developer Consolessa. linkki saada yksityiskohtaiset tiedot Google Client ID ja Secret.

Kun Google Client ID:n ja Secret-nimen sallitte, voitte liittää ne ohjelmiinne.

    "Auth" :{
"GoogleClientId": "",
"GoogleClientSecret": ""
}

Vaikka niitä ei pitäisikään tarkistaa lähteen valvonnassa. Paikallisen kehityksen sijaan voi käyttää Secrets-tietokantaa:

secrets.png

Siihen voi lisätä Googlen Client ID: n ja Secret -nimen.

    "Auth" :{
  "GoogleClientId": "ID",
  "GoogleClientSecret": "CLIENTSECRET"
}

Google Auth -järjestelmä POCO:n avulla

Huomautan, että käytän Steve Smithin mukautettua versiota IConfigSection (, jonka Phil Haack hiljattain on tehnyt tunnetuksi Tämä on vältettävä IOptions-asioita, jotka ovat mielestäni hieman hankalat ( ja joita tarvitsen harvoin, koska en lähes koskaan muuta konfiguraatiota omien skenaariojeni käyttöönoton jälkeen.

Minussa teen tämän, mikä antaa minulle mahdollisuuden saada osan nimi itse luokkasta:

Click to expand


namespace Mostlylucid.Config;

public static class ConfigExtensions {
    public static TConfig ConfigurePOCO<TConfig>(this IServiceCollection services, IConfiguration configuration)
        where TConfig : class, new() {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (configuration == null) throw new ArgumentNullException(nameof(configuration));
        
        var config = new TConfig();
        configuration.Bind(config);
        services.AddSingleton(config);
        return config;
    }
    
    public static TConfig Configure<TConfig>(this WebApplicationBuilder builder)
        where TConfig : class, IConfigSection, new() {
        var services = builder.Services;
        var configuration = builder.Configuration;
        var sectionName = TConfig.Section;
        return services.ConfigurePOCO<TConfig>(configuration.GetSection(sectionName));
    }
    

    public static TConfig GetConfig<TConfig>(this WebApplicationBuilder builder)
        where TConfig : class, IConfigSection, new() {
        var configuration = builder.Configuration;
        var sectionName = TConfig.Section;
        var section = configuration.GetSection(sectionName).Get<TConfig>();
        return section;
        
    }
    
    public static Dictionary<string, object> GetConfigSection(this IConfiguration configuration, string sectionName) {
        var section = configuration.GetSection(sectionName);
        var result = new Dictionary<string, object>();
        foreach (var child in section.GetChildren()) {
            var key = child.Key;
            var value = child.Value;
            result.Add(key, value);
        }
        
        return result;
    }
    
    public static Dictionary<string, object> GetConfigSection<TConfig>(this WebApplicationBuilder builder)
        where TConfig : class, IConfigSection, new() {
        var configuration = builder.Configuration;
        var sectionName = TConfig.Section;
        return configuration.GetConfigSection(sectionName);
    }
}

public interface IConfigSection {
    public static abstract string Section { get; }
}
Näin ollen Auth näyttää olevan
public class Auth : IConfigSection
{
    public static string Section => "Auth";
    public string GoogleClientId { get; set; }
    public string GoogleClientSecret { get; set; }
    
    public string AdminUserGoogleId { get; set; }
    
}

Kun käytän statista yhteysmenetelmää osuuden nimeämiseksi.

Sitten voin tehdä tämän aloitteessani:

var auth = builder.GetConfig<Auth>();

Joka tapauksessa takaisin Google-asioihin!

Ohjelmien.cs-järjestelmä

Jotta itse asiassa lisätään tämä

services.AddCors(options =>
{
    options.AddPolicy("AllowMostlylucid",
        builder =>
        {
            builder.WithOrigins("https://www.mostlylucid.net")
                .WithOrigins("https://mostlylucid.net")
                .WithOrigins("https://localhost:7240")
                .AllowAnyHeader()
                .AllowAnyMethod();
        });
});

builder.Services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
   
      
    })
    .AddCookie()
    .AddGoogle(options =>
    {
        options.ClientId = auth.GoogleClientId;
        options.ClientSecret = auth.GoogleClientSecret;
    });

Teidän on otettava huomioon seuraavat asiakirjat:', ', CORS-merkinnät ja , sekä Googlen identiteettikonsolessa

googleidentity.png

Näin varmistetaan, että Google Auth-järjestelmää voidaan käyttää vain niiltä alueilta, jotka olette määrittäneet.

Google Auth In Razor

Minun _Layout.cshtml Minulla on tämä Javascript, tämä on se paikka, jossa asetan Google-puitteet ja aktivoin puhelun takaisin, joka tallentaa ASP:n

Google JS

<script src="https://accounts.google.com/gsi/client" async defer></script>

Tämä on jäljempänä olevan koodin lasku



        
        function renderButton(element)
        {
            google.accounts.id.renderButton(
                element,
                {
                    type: "standard",
                    size: "large",
                    width: 200,
                    theme: "filled_black",
                    text: "sign_in_with",
                    shape: "rectangular",
                    logo_alignment: "left"
                }
            );
        }
        function initGoogleSignIn() {
            google.accounts.id.initialize({
                client_id: "839055275161-u7dqn2oco2729n6i5mk0fe7gap0bmg6g.apps.googleusercontent.com",
                callback: handleCredentialResponse
            });
            const element = document.getElementById('google_button');
            if (element) {
                renderButton(element);
            }
            const secondElement = document.getElementById('google_button2');
            if (secondElement) {
                renderButton(secondElement);
            }
           
        }

        function handleCredentialResponse(response) {
            if (response.credential) {
                const xhr = new XMLHttpRequest();
                xhr.open('POST', '/login', true);
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.onload = function () {
                    if (xhr.status === 200) {
                        window.location.reload();
                    } else {
                        console.error('Failed to log in.');
                    }
                };
                xhr.send(JSON.stringify({ idToken: response.credential }));
            } else {
                console.error('No credential in response.');
            }
        }

        window.onload = initGoogleSignIn;

Tässä voitte nähdä, että minulla on jopa kaksi div-elementtiä sivussa id google_muuto ja google _muoto

TIP: Jos olette käyttämässä Tailwindia,, voitte peitellä langanpuskea, jotta se toimisi oikein pimeässä muodossa.

<div class="w-[200px] h-[39px] overflow-hidden rounded">
    <div id="google_button">
    </div>
</div>

Edellä esitetyssä JavaScript-ohjelmissa lähetän tämän takaisin Controllerin toiminnalle, joka kutsutaan Login. Siihen käsitellään Google Auth.

      const xhr = new XMLHttpRequest();
                xhr.open('POST', '/login', true);
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.onload = function () {
                    if (xhr.status === 200) {
                        window.location.reload();
                    } else {
                        console.error('Failed to log in.');
                    }
                };
                xhr.send(JSON.stringify({ idToken: response.credential }));

Google Auth hallinnoinnissa

Controller on täällä' se ' on melko yksinkertainen se vain ottaa lähetetyn JWTM SK2 dekodistaa sen ja käyttää sitä liittymiseen appiin.

    [Route("login")]
        [HttpPost]
        public async Task<IActionResult> HandleGoogleCallback([FromBody] GoogleLoginRequest request)
        {
            var handler = new JwtSecurityTokenHandler();
            var jsonToken = handler.ReadToken(request.IdToken) as JwtSecurityToken;

            if (jsonToken == null)
            {
                return BadRequest("Invalid token");
            }

            var claimsIdentity = new ClaimsIdentity(
                jsonToken.Claims,
                GoogleDefaults.AuthenticationScheme);

            var authProperties = new AuthenticationProperties
            {
                IsPersistent = true
            };

            await HttpContext.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(claimsIdentity),
                authProperties);

            return Ok();
        }
    }

PANEE MERKILLE: Tämä ei ole't prefect, koska se on ottanut esille vaatimuksen nimet ( ne ovat kaikki alhaisempia tapauksia M SK3 mutta se toimii nyt .

Controller Base Class -järjestelmä, jolla otetaan käyttöön login-ominaisuuksia

Omassa BaseControllerissani otan käyttöön tarvittavat ominaisuudet;

      public record LoginData(bool loggedIn, string? name, string? avatarUrl, string? identifier);
    
    protected LoginData GetUserInfo()
    {
        var authenticateResult = HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme).Result;
        if (authenticateResult.Succeeded)
        {
            var principal = authenticateResult.Principal;
            if(principal == null)
            {
                return new LoginData(false, null, null, null);
            }
            var name = principal.FindFirst("name").Value;
            var avatarUrl =principal.FindFirst("picture").Value;
            var nameIdentifier = principal.FindFirst("sub");
            return new LoginData(true, name, avatarUrl, nameIdentifier?.Value);
        }
        return new LoginData(false,null,null,null);
    }

Tämä antaa mahdollisuuden käyttää Gooogle Authentication -järjestelmää ilman ASP:n käyttämistä.

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.