This commit is contained in:
mmrbnjd
2025-06-29 15:29:51 +03:30
parent 279940198a
commit 86de5d3e39
13 changed files with 292 additions and 22 deletions

View File

@@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System.Reflection;
using System.Text;
namespace Hushian.Application
{
public static class ApplicationServicesRegistration
{
public static void ConfigureApplicationServices(this IServiceCollection services,
IConfiguration configuration)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
ValidIssuer = configuration["JwtSettings:Issuer"],
ValidAudience = configuration["JwtSettings:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtSettings:Key"]))
};
});
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hushian.Application.Constants
{
public static class CustomClaimTypes
{
public const string Uid = "uid";
}
}

View File

@@ -6,6 +6,15 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
<PackageReference Include="FluentValidation" Version="11.11.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.3.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.6" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\Hushian.Domain\Hushian.Domain.csproj" />

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hushian.Application.Models
{
public class JwtSettings
{
public string Key { get; set; }
public string Issuer { get; set; }
public string Audience { get; set; }
public int DurationInMinutes { get; set; }
}
}

View File

@@ -0,0 +1,87 @@
using Common.Models.Auth;
using Common.Models.Auth.CompanySide;
using Common.Models.Auth.UserSide;
using Hushian.Application.Constants;
using Hushian.Application.Contracts.Persistence;
using Hushian.Application.Models;
using Hushian.Domain.Entites;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace Hushian.Application.Services
{
public class AuthService
{
private readonly JwtSettings _jwtSettings;
private readonly IGenericRepository<Company> _CompanyRepository;
private readonly IGenericRepository<User> _UserRepository;
private readonly IGenericRepository<Exper> _ExperRepository;
private readonly VerificationService _verificationService;
public AuthService(IOptions<JwtSettings> jwtSettings)
{
_jwtSettings = jwtSettings.Value;
}
public async Task<ResponseBase<AuthResponse>> AuthenticationFromCompanySide
(AuthRequestFromCompanySide auth)
{
ResponseBase<AuthResponse> Response = new();
return Response;
}
public async Task<ResponseBase<int>> AuthenticationFromUserSide
(AuthRequestFromUserSide auth)
{
ResponseBase<int> Response = new();
if (!await _UserRepository.Get().AnyAsync(a => a.Mobile == auth.Mobile))
{
if (!await _UserRepository.ADDBool(new User() { Mobile = auth.Mobile, FullName = auth.FullName }))
{
Response.Errors.Add("خطا در کاربری");
}
}
if (Response.Errors.Count==0)
{
Response.Value = await _verificationService.GenerateCodeForLoginUser(auth.Mobile);
Response.Success = true;
}
return Response;
}
public async Task<JwtSecurityToken> GenerateToken(string UserName, int userId)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub,UserName),
new Claim(CustomClaimTypes.Uid,userId.ToString())
};
var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.Key));
var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256);
var jwtSecurityToken = new JwtSecurityToken(
issuer: _jwtSettings.Issuer,
audience: _jwtSettings.Audience,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(_jwtSettings.DurationInMinutes),
signingCredentials: signingCredentials);
//user.Token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
//var resultupdateuser = await _userManager.UpdateAsync(user);
return jwtSecurityToken;
}
}
}

View File

@@ -0,0 +1,102 @@
using Common.Contracts.Infrastructure;
using Common.Dtos.Verification;
using Common.Enums;
using Common.Models.Auth;
using Hushian.Application.Contracts.Persistence;
using Hushian.Application.Models;
using Hushian.Domain.Entites;
using Identity.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hushian.Application.Services
{
public class VerificationService
{
private readonly IGenericRepository<VerificationCode> _VerificationCodeRepository;
private readonly IMessageSender _messageSender;
private readonly IGenericRepository<User> _UserRepository;
private readonly AuthService _authService;
public async Task<int> GenerateCodeForLoginUser(string Mobile)
{
string Code = await GenerateCode();
var response= await _VerificationCodeRepository.ADD
(new Identity.Models.VerificationCode(VerificationCodeType.Login, Code, Mobile));
await _messageSender.SendMassage(new Models.Message.Message()
{
msg = Code,
To = Mobile
});
return response.ID;
}
public async Task<ResponseBase<AuthResponse>> VerificationCode(ConfirmedCodeDto model)
{
var response = new ResponseBase<AuthResponse>();
var resultConf=await _VerificationCodeRepository.Get()
.FirstOrDefaultAsync(w => w.ID == model.Id && w.Code == model.code && w.Type == model.codeType);
if (resultConf!=null)
{
if (resultConf.Type == VerificationCodeType.Login)
{
var User= await _UserRepository.Get().FirstOrDefaultAsync(w => w.Mobile == resultConf.Mobile);
if (User!=null)
{
response.Success = true;
response.Value = new AuthResponse()
{
Fullname = User.FullName,
Id = User.ID,
MobileOrUserName = User.Mobile,
Token = new JwtSecurityTokenHandler().WriteToken(await _authService.GenerateToken(User.Mobile, User.ID))
};
}
else
{
response.Errors.Add("کاربری یافت نشد");
}
}
else if (resultConf.Type == VerificationCodeType.ForgetPassword)
{
if ((string.IsNullOrEmpty(model.value) || model.value.Length < 5))
response.Errors.Add("کلمه عبور باید بیشتر از 5 کاراکتر باشد");
else
{
}
}
else if (resultConf.Type == VerificationCodeType.PhoneNumberConfirmed)
{
}
else
{
response.Errors.Add("احراز صحیح نمی باشد");
}
await _VerificationCodeRepository.DELETE(resultConf);
}
else
{
response.Errors.Add("احراز یافت نشد");
}
return response;
}
private async Task<string> GenerateCode()
{
int Code = Random.Shared.Next(1000, 9000);
while (await _VerificationCodeRepository.Get().AnyAsync(w => w.Code == Code.ToString()))
Code = Random.Shared.Next(1000, 9000);
return Code.ToString();
}
}
}