Files
tiku-backend.net/Tiku.Infrastructure/Auth/SessionService.cs
2026-07-26 12:51:56 +08:00

69 lines
2.0 KiB
C#

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);
}
}