#oauth changed GoogleController for the jwt flow ( using a common token if we connect from our app or from google )

This commit is contained in:
Dominic Villemure
2024-06-09 23:44:37 -04:00
parent ac87aeb4c4
commit 6f76cb2084
16 changed files with 338 additions and 842 deletions

View File

@@ -1,6 +1,6 @@
using System.Security.Claims;
using Hutopy.Domain.Interfaces;
using Hutopy.Infrastructure.Services;
using Hutopy.Application.Common.Interfaces;
using Hutopy.Infrastructure.Utils;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Facebook;
@@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Mvc;
namespace Hutopy.Web.Controllers;
public class FacebookController(IUserService userService) : Controller
public class FacebookController(IIdentityService identityService) : Controller
{
[HttpGet("/api/facebook/sign-in")]
public async Task SignIn()
@@ -27,10 +27,10 @@ public class FacebookController(IUserService userService) : Controller
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 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>
{
@@ -40,13 +40,13 @@ public class FacebookController(IUserService userService) : Controller
new(ClaimTypes.Surname, familyName)
}, CookieAuthenticationDefaults.AuthenticationScheme);
if (await userService.FindUserByEmailAsync(email) != null)
if (await identityService.FindUserByEmailAsync(email) != null)
{
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Redirect("/");
}
await userService.CreateUserAsync(email, givenName, givenName, familyName, RandomGenerator.RandomString(24));
await identityService.CreateUserAsync(email, givenName, givenName, familyName, RandomGenerator.RandomString(24));
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Redirect("/");
}

View File

@@ -1,53 +1,70 @@
using System.Security.Claims;
using Hutopy.Domain.Interfaces;
using Hutopy.Infrastructure.Services;
using Hutopy.Application.Common.Interfaces;
using Hutopy.Infrastructure.Utils;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
namespace Hutopy.Web.Controllers;
public class GoogleController(IUserService userService) : Controller
public class GoogleController(IIdentityService identityService, IHttpClientFactory httpClientFactory) : Controller
{
[HttpGet("/api/google/sign-in")]
public async Task SignIn()
[HttpPost("/api/google/sign-in")]
public async Task<IActionResult> SignIn([FromBody] GoogleSignInRequest request)
{
await HttpContext.ChallengeAsync(GoogleDefaults.AuthenticationScheme, new AuthenticationProperties
var httpClient = httpClientFactory.CreateClient();
// Verify the token with Google
var response = await httpClient.GetAsync($"https://www.googleapis.com/oauth2/v1/userinfo?access_token={request.AccessToken}");
if (!response.IsSuccessStatusCode)
{
RedirectUri = Url.Action("Authorize")
});
}
public async Task<IActionResult> Authorize()
{
var authenticateResult = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);
return BadRequest("Invalid Google token.");
}
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var email = payload["email"]?.ToString() ?? "";
var name = payload["name"]?.ToString() ?? "";
var givenName = payload["given_name"]?.ToString() ?? "";
var familyName = payload["family_name"]?.ToString() ?? "";
if (string.IsNullOrEmpty(email))
{
return BadRequest("Google token did not contain an email.");
}
// Check if user exists or create a new one
var user = await identityService.FindUserByEmailAsync(email);
if (user == null)
{
await identityService.CreateUserAsync(email, email, givenName, familyName, RandomGenerator.RandomString(24));
user = await identityService.FindUserByEmailAsync(email);
}
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>
if (user is null)
{
return BadRequest("Unable to find or create the user.");
}
// Sign in the user
var claims = 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));
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Redirect("/");
var jwtToken = JwtTokenHelper.GenerateJwtToken("https://hutopy.com", "Hutopy", "V3J3bWFuUml3ZVpQbmxlWmZhWEo3ZkJSZ01YbHBwS24=", user.Id!);
return Ok(new { accessToken = jwtToken, email });
}
public class GoogleSignInRequest
{
public required string AccessToken { get; set; }
}
}