112 lines
4.2 KiB
C#
112 lines
4.2 KiB
C#
using MediatR;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Options;
|
|
using Modules.User.Application.Models;
|
|
using Modules.User.Application.Queries;
|
|
using Modules.User.Application.Settings;
|
|
using System.Net.Http.Json;
|
|
using System.Security.Claims;
|
|
|
|
namespace Modules.User.Application;
|
|
|
|
public class UserContext
|
|
{
|
|
private readonly IMediator _mediator;
|
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
private readonly JwtSettings _jwtSettings;
|
|
private Models.User? _user;
|
|
|
|
public UserContext(IOptionsMonitor<JwtSettings> jwtSettingsOptions, IMediator mediator, IHttpContextAccessor httpContextAccessor, IConfiguration configuration)
|
|
{
|
|
_mediator = mediator;
|
|
_httpContextAccessor = httpContextAccessor;
|
|
_jwtSettings = jwtSettingsOptions.CurrentValue;
|
|
}
|
|
|
|
public JwtSettings GetJwtSettings() => _jwtSettings;
|
|
|
|
public async Task<Models.User> GetUserInfo(CancellationToken cancellationToken = default)
|
|
{
|
|
var a = _httpContextAccessor.HttpContext?.User.FindFirstValue(Constants.SessionIdKey);
|
|
if (_user == null || !_user.IsAuthenticated)
|
|
{
|
|
if (Guid.TryParse(_httpContextAccessor.HttpContext?.User.FindFirstValue(Constants.AccountIdKey), out Guid accountId))
|
|
_user = await _mediator.Send(new GetUserQuery
|
|
{
|
|
AccountId = accountId,
|
|
SessionId = Guid.TryParse(_httpContextAccessor.HttpContext?.User.FindFirstValue(Constants.SessionIdKey), out Guid sessionId) ? sessionId : null,
|
|
}, cancellationToken);
|
|
else _user = new Models.User();
|
|
//await RetrieveUserInfo(_user);
|
|
if (!_user.IsAuthenticated) { }
|
|
}
|
|
return _user;
|
|
}
|
|
|
|
//private async Task RetrieveUserInfo(Models.User user)
|
|
//{
|
|
// var ip = GetClientIp();
|
|
// var ipAddressWithoutPort = ip?.Split(':')[0];
|
|
// var location = await GetLocation(ipAddressWithoutPort);
|
|
// var clientInfo = new ClientInfo
|
|
// {
|
|
// Ip = !string.IsNullOrWhiteSpace(ipAddressWithoutPort) ? ipAddressWithoutPort : null,
|
|
// UserAgent = _httpContextAccessor.HttpContext?.Request.Headers.UserAgent,
|
|
// Location = location,
|
|
// };
|
|
// user.ClientInfo = clientInfo;
|
|
//}
|
|
|
|
internal string? GetUserAgent() => _httpContextAccessor.HttpContext?.Request.Headers.UserAgent;
|
|
|
|
private string? GetClientIp()
|
|
{
|
|
var ip = _httpContextAccessor.HttpContext?.GetServerVariable("HTTP_X_FORWARDED_FOR");
|
|
if (string.IsNullOrWhiteSpace(ip)) ip = _httpContextAccessor.HttpContext?.Request.Headers["CF-CONNECTING-IP"];
|
|
if (string.IsNullOrWhiteSpace(ip)) ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString();
|
|
return ip?.Trim();
|
|
}
|
|
|
|
//вынести в сервис
|
|
internal async Task<Location?> GetLocation(string? ip)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(ip))
|
|
{
|
|
ip = GetClientIp();
|
|
if (string.IsNullOrWhiteSpace(ip))
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
var client = new HttpClient() { BaseAddress = new Uri("http://ip-api.com") };
|
|
try
|
|
{
|
|
var response = await client.GetFromJsonAsync<IpApiResponse>($"/json/{ip}");
|
|
return response == null || (!response.lat.HasValue || !response.lon.HasValue) ? null : new Location
|
|
{
|
|
Latitude = response.lat.Value,
|
|
Longutude = response.lon.Value,
|
|
Country = response.country,
|
|
Region = response.regionName,
|
|
};
|
|
}
|
|
catch { return null; }
|
|
}
|
|
|
|
public sealed class IpApiResponse
|
|
{
|
|
public string? status { get; set; }
|
|
public string? continent { get; set; }
|
|
public string? country { get; set; }
|
|
public string? regionName { get; set; }
|
|
public string? city { get; set; }
|
|
public string? district { get; set; }
|
|
public string? zip { get; set; }
|
|
public double? lat { get; set; }
|
|
public double? lon { get; set; }
|
|
public string? isp { get; set; }
|
|
public string? query { get; set; }
|
|
}
|
|
} |