# ASP.NET पहचान डाटाबेस के बिना गूगल ऑथ जोड़ना

<!--category-- ASP.NET, Google Auth -->
<datetime class="hidden">2024-08-05T08:06</datetime>

## परिचय

इस एप्लिकेशन में मैं लॉगिन करने के लिए टिप्पणी जोड़ने की अनुमति देने का एक सिम्पल तंत्र जोड़ना चाहता था।

डाटाबेस किसी भी अनुप्रयोग का एक शक्तिशाली घटक है लेकिन वे जटिलता भी जोड़ते हैं

[TOC]

## चरण

सबसे पहले आपको Google Auth को Google Developer Console में सेटअप करने की जरूरत है. आप इस में चरणों का पालन कर सकते हैं [लिङ्क](https://developers.google.com/identity/gsi/web/guides/overview) आपके लिए अपने विवरण सेटअप करने के लिए Google क्लाइंट आईडी और Secret

एक बार जब आप अपने Google क्लाइंट आईडी और Secret है

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

हालांकि आप इन को स्रोत नियंत्रण में नहीं जाँचना चाहिए

![secrets.png](secrets.png)

वहाँ आप अपने Google क्लाइंट आईडी और Secret जोड़ सकते हैं (देखें कि आपका क्लाइन्ट आईडी नहीं है

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

## POCO के साथ Google Auth को कॉन्फ़िगर करना

नोट मैं स्टीव स्मिथ के परिवर्धित संस्करण का उपयोग करता हूँ
यह IOptions सामान से बचने के लिए है जो मैं एक bit clunky पाया जाता है & #44; ( & #39; और दुर्लभ रूप से की जरूरत है क्योंकि मैं अपने परिदृश्यों में विनियोजन के बाद लगभग कभी कॉन्फ़िगरेशन बदल नहीं करता है

mine में मैं यह करता हूँ जो मुझे वर्ग स्वयं से धारा नाम प्राप्त करने के लिए अनुमति देता है

<details>
<summary>Click to expand</summary>

```csharp


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; }
}
```

</details>
तो मेरी ऑथ की तरह दिखती है

```csharp
public class Auth : IConfigSection
{
    public static string Section => "Auth";
    public string GoogleClientId { get; set; }
    public string GoogleClientSecret { get; set; }
    
    public string AdminUserGoogleId { get; set; }
    
}
```

जहां मैं एक स्थिर अंतरफलक विधि का उपयोग धारा नाम प्राप्त करने के लिए करता हूँ

तब मेरे स्टार्टअप में मैं यह कर सकता हूँ

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

किसी भी तरह वापस google stuff!

## प्रोग्राम.cs सेटअप

वास्तव में यह जोड़ने के लिए

```csharp
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;
    });
```

आपll note there's CORS entries here, you also need to setup these in the google identity console

![googleidentity.png](googleidentity.png)

यह सुनिश्चित करता है कि Google Auth केवल आप निर्दिष्ट डोमेनों से उपयोग किया जा सकता है

## Google Auth In Razor

मेरे _सजावट.cshtml मेरे पास यह जावास्क्रिप्ट है, यहाँ मैं अपनी गूगल बटन सेटअप करता हूँ और एक कॉलबैक ट्रिगर करता है जो ASP को लॉग करता है

# गूगल JS

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

यह नीचे कोड के लिए धीमी है

```javascript


        
        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;

```

यहाँ आप देख सकते हैं कि मैं id google के साथ पृष्ठ में दो div तत्वों तक है google </_>button और google ></_>buttons </2.> इन तत्वों से Google JS बटनों को render करेगा

टीप: यदि आप Tailwind का उपयोग कर रहे हैं, आप बटन div सही रूप से dark मोड में काम करने के लिए shink कर सकते हैं M SK2 अन्यथा यह बटन के चारों ओर एक सफेद पृष्ठभूमि बनाता है

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

उपरोक्त जावास्क्रिप्ट में मैं यह वापस एक नियंत्रक क्रिया को पोस्ट करता हूँ जिसका नाम लॉगिन है

```javascript
      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 }));
```

## कंट्रोलर में गूगल ऑथ

नियंत्रक यहाँ है।

```csharp
    [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();
        }
    }
```

नोट: यह नहीं है'प्रिफैट के रूप में यह दावा नामों को शामिल करता है M SK2वे सभी निचले अक्षर हैंMSC3 लेकिन यह अब के लिए काम करता है

### लॉगिन गुण निकालने के लिए नियंत्रक आधार वर्ग

मेरे बेस कंट्रोलर में मैं आवश्यक गुण निकालता हूँ

```csharp
      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);
    }
```

यह आपको ASP के उपयोग किए बिना Gooogle प्रमाणीकरण का उपयोग करने देता है