Feature: Google and Facebook sign-in

This commit is contained in:
Kamigen
2024-06-05 16:01:44 -04:00
parent fc0c94306b
commit aa8a5ad93d
6 changed files with 96 additions and 34 deletions

View File

@@ -0,0 +1,53 @@
using System.Security.Claims;
using Hutopy.Domain.Interfaces;
using Hutopy.Infrastructure.Services;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Facebook;
using Microsoft.AspNetCore.Mvc;
namespace Hutopy.Web.Controllers;
public class FacebookController(IUserService userService) : Controller
{
[HttpGet("/api/facebook/sign-in")]
public async Task SignIn()
{
await HttpContext.ChallengeAsync(FacebookDefaults.AuthenticationScheme, new AuthenticationProperties
{
RedirectUri = Url.Action("Authorize")
});
}
public async Task<IActionResult> Authorize()
{
var authenticateResult = await HttpContext.AuthenticateAsync(FacebookDefaults.AuthenticationScheme);
if (!authenticateResult.Succeeded) return BadRequest();
var claims = authenticateResult.Principal.Claims.ToList();
var name = claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
var email = claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value;
var givenName = claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName)?.Value;
var familyName = claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname)?.Value;
var claimsIdentity = new ClaimsIdentity(new List<Claim>
{
new(ClaimTypes.Name, name),
new(ClaimTypes.Email, email),
new(ClaimTypes.GivenName, givenName),
new(ClaimTypes.Surname, familyName)
}, CookieAuthenticationDefaults.AuthenticationScheme);
if (await userService.FindUserByEmailAsync(email) != null)
{
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Redirect("/");
}
await userService.CreateUserAsync(email, givenName, givenName, familyName, RandomGenerator.RandomString(24));
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Redirect("/");
}
}

View File

@@ -1,6 +1,6 @@
using System.Security.Claims;
using Google.Apis.Oauth2.v2.Data;
using Hutopy.Domain.Interfaces;
using Hutopy.Infrastructure.Services;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
@@ -8,52 +8,45 @@ using Microsoft.AspNetCore.Mvc;
namespace Hutopy.Web.Controllers;
public class GoogleController(
IUserService userService) : Controller
public class GoogleController(IUserService userService) : Controller
{
[HttpGet("/api/google/sign-in")]
public async Task SignIn()
{
await HttpContext.ChallengeAsync(GoogleDefaults.AuthenticationScheme, new AuthenticationProperties
{
RedirectUri = Url.Action("Callback"),
RedirectUri = Url.Action("Authorize")
});
}
public async Task<IActionResult> Callback()
public async Task<IActionResult> Authorize()
{
var authenticateResult = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var authenticateResult = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);
if (!authenticateResult.Succeeded)
{
return BadRequest();
}
if (!authenticateResult.Succeeded) return BadRequest();
var claims = authenticateResult.Principal.Claims.ToList();
var userInfo = new Userinfo
{
Name = claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value,
Email = claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value,
GivenName = claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName)?.Value,
FamilyName = claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname)?.Value
};
var name = claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
var email = claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value;
var givenName = claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName)?.Value;
var familyName = claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname)?.Value;
var claimsIdentity = new ClaimsIdentity(new List<Claim>
{
new(ClaimTypes.Name, userInfo.Name),
new(ClaimTypes.Email, userInfo.Email),
new(ClaimTypes.GivenName, userInfo.GivenName),
new(ClaimTypes.Surname, userInfo.FamilyName)
new(ClaimTypes.Name, name),
new(ClaimTypes.Email, email),
new(ClaimTypes.GivenName, givenName),
new(ClaimTypes.Surname, familyName)
}, CookieAuthenticationDefaults.AuthenticationScheme);
if (await userService.FindUserByEmailAsync(userInfo.Email) != null) // TODO: Do we need to check for null ?
if (await userService.FindUserByEmailAsync(email) != null)
{
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Redirect("/");
}
await userService.CreateUserAsync(userInfo);
await userService.CreateUserAsync(email, givenName, givenName, familyName, RandomGenerator.RandomString(24));
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Redirect("/");
}