feat: add local authentication
This commit is contained in:
68
Tiku.Infrastructure/Auth/SessionService.cs
Normal file
68
Tiku.Infrastructure/Auth/SessionService.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Tiku.Application.Auth;
|
||||
using Tiku.Application.Security;
|
||||
using Tiku.Domain.Tenancy;
|
||||
using Tiku.Infrastructure.Persistence;
|
||||
|
||||
namespace Tiku.Infrastructure.Auth;
|
||||
|
||||
public sealed class SessionService(
|
||||
TikuDbContext dbContext,
|
||||
ITokenService tokenService,
|
||||
IOptions<JwtOptions> options) : ISessionService
|
||||
{
|
||||
private readonly JwtOptions options = options.Value;
|
||||
|
||||
public string GenerateRefreshToken()
|
||||
{
|
||||
return Base64UrlEncoder.Encode(RandomNumberGenerator.GetBytes(64));
|
||||
}
|
||||
|
||||
public string HashRefreshToken(string refreshToken)
|
||||
{
|
||||
var hash = SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(refreshToken));
|
||||
return Convert.ToHexString(hash).ToLowerInvariant();
|
||||
}
|
||||
|
||||
public async Task<AuthTokenPair> IssueAsync(
|
||||
Guid userId,
|
||||
string? phone,
|
||||
string? email,
|
||||
TenantMembership membership,
|
||||
string provider,
|
||||
string? ipAddress,
|
||||
string? userAgent,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var refreshToken = GenerateRefreshToken();
|
||||
var session = new AuthSession
|
||||
{
|
||||
TenantId = membership.TenantId,
|
||||
UserId = userId,
|
||||
TokenHash = HashRefreshToken(refreshToken),
|
||||
Provider = provider,
|
||||
ExpiresAt = DateTimeOffset.UtcNow.AddDays(options.RefreshTokenDays),
|
||||
IpAddress = ipAddress,
|
||||
UserAgent = userAgent
|
||||
};
|
||||
|
||||
dbContext.AuthSessions.Add(session);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
var accessToken = tokenService.CreateAccessToken(
|
||||
userId,
|
||||
session.Id,
|
||||
phone,
|
||||
email,
|
||||
membership);
|
||||
|
||||
return new AuthTokenPair(
|
||||
accessToken.Token,
|
||||
refreshToken,
|
||||
accessToken.ExpiresAt,
|
||||
session.ExpiresAt);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user