Доdanie Google Auth без ASP.NET Identity Database
Введение
У цій програмі я хотів додати механізм зразка, що дозволяє при вході додавати коментарі ( і деякі адміністративні завдання ) до aplikacji МSK2 Я хотів використати Google Auth для цього celu \ . Я не хотів використовувати ASP \ МSK4 \ NET Identity базу даних для цього призначення . \ Я хотіла залишити програму такою простою, як це можливо довгий час | . \
Базики даних - це потужна складова будь-якої додатки, але вони також додають і складності.
Шаг
Спочатку треба встановити Google Auth в Google Developer Console. Ви можете зробити наступні кроки: зв 'язок щоб отримати ваші дані для вас Google Client ID та Secret.
Після того, як у вас є Google Client ID та Secret,, ви можете додати їх до ваших настроїв
"Auth" :{
"GoogleClientId": "",
"GoogleClientSecret": ""
}
Звісно, ви не маєте перевіряти їх на контролі над джерелом. Замість локального розвитку ви можете використовувати файл секретів:

Там ви можете додати вашу Google Client ID і секретну. ( зауважте, що ваші клієнтські ID не конфіденційні.
"Auth" :{
"GoogleClientId": "ID",
"GoogleClientSecret": "CLIENTSECRET"
}
Konfiguracja Google Auth з POCO
Зверніть увагу, я використовую модифіковану версію IConfigSection Стіва Сміта Це для того, щоб уникнути IOptions речей, які я вважаю трохи незграбними ( і рідко потребують, тому що я майже ніколи не змінюю конфігурацію після застосування у моїх сценаріїв ).
У моїй я роблю це, що дозволяє мені отримати ім 'я секції з самого класу:
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; }
}
public class Auth : IConfigSection
{
public static string Section => "Auth";
public string GoogleClientId { get; set; }
public string GoogleClientSecret { get; set; }
public string AdminUserGoogleId { get; set; }
}
Де я використовую статичний метод інтерфейсу для отримання назви секції.
Тоді я можу зробити це в своєму стартеті:
var auth = builder.GetConfig<Auth>();
В будь-якому випадку повернімося до Google stuff!
Установка програми.cs
Щоб додати це
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;
});
Ви' помічаєте там ' вхідні записи CORS тут МSK2 вам також потрібно встановити їх у консольі Google Identity

Це гарантує, що Auth Google можна використовувати лише з домен, які ви встановлюєте.
Google Auth In Razor
У моєму _У мене є цей Javascript, тут я встановлюю свої кнопки Google і запускаю зворотний дзвінок, який записує ASPM SK2NET app.
Google JS
<script src="https://accounts.google.com/gsi/client" async defer></script>
Це падіння для коду нижче
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;
Тут ви бачите, що у мене є до двох div елементів на сторінці з id google_ кнопка і googleМSK1 кнопкиM SK2 Це елементи, які Google JS перетворить на кнопки в.
TIP: Якщо ви використовуєте Tailwind,, ви можете втиснути кнопку div, щоб працювати правильно у темному режимі M SK2 інакше вона відображає білий фон навколо кнопки )
<div class="w-[200px] h-[39px] overflow-hidden rounded">
<div id="google_button">
</div>
</div>
У JavaScript я відтворюю це назад до дії Controller під назвою Login. Тут я обробляю 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 у контроллері
Тут є контроллер. МСК0, МСК1 досить простий. Просто треба записати JWT. МSK2 розшифровує, а потім використовує його для входу в додаток.
[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();
}
}
NOTA: Це не МСК1 не префект, тому що він виділяє імена відповідальності. M SK2 всі вони нижчі, МSK3 але це працює на даний момент
Базова клас контроллера для видобутку властивостей входу
У своєму контроллері я виділяю необхідні властивості;
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);
}
І це ─ МСК0 ─ це ‒ МSK1 ─ Це дозволяє використовувати аутентифікацію Gooogle без використання ASP ─ . ─ NET Identity database ─.