namespace WebApi.Helpers; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using backend.Services; using backend.Helpers; using Google.Apis.Auth; using System.Text.Json; using Newtonsoft.Json; public class JwtMiddleware { private readonly RequestDelegate _next; private readonly AppSettings _appSettings; private static readonly HttpClient client = new HttpClient(); public JwtMiddleware(RequestDelegate next, IOptions appSettings) { _next = next; _appSettings = appSettings.Value; } public async Task Invoke(HttpContext context, IUserService userService) { var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); if (token != null && token != "null") await attachUserToContext(context, userService, token); await _next(context); } private async Task attachUserToContext(HttpContext context, IUserService userService, string token) { try { var fbResult = await this.ValidateFacebookToken(token); if (fbResult != null) { context.Items["User"] = fbResult; return; } var tokenHandler = new JwtSecurityTokenHandler(); var key = System.Text.Encoding.ASCII.GetBytes(_appSettings.Secret); tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false, ClockSkew = TimeSpan.Zero }, out SecurityToken validatedToken); var jwtToken = (JwtSecurityToken)validatedToken; var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value); context.Items["User"] = userId; } catch { try { var result = await GoogleJsonWebSignature.ValidateAsync(token); context.Items["User"] = result.Email; } catch { // do nothing } } } private async Task ValidateFacebookToken(string token) { try { var stringTask = await client.GetStringAsync("https://graph.facebook.com/me?fields=email&access_token=" + token); var obj = JsonConvert.DeserializeObject(stringTask); return obj.email; } catch { return null; } } internal class FacebookResult { public string email { get; set; } public string id { get; set; } } }