forked from gongxuegit/tiku-backend.net
feat: enforce tenant isolation and shared question bank
This commit is contained in:
@@ -16,9 +16,29 @@ public sealed class SessionService(
|
||||
{
|
||||
private readonly JwtOptions options = options.Value;
|
||||
|
||||
public string GenerateRefreshToken()
|
||||
public string GenerateRefreshToken(Guid tenantId, Guid sessionId)
|
||||
{
|
||||
return Base64UrlEncoder.Encode(RandomNumberGenerator.GetBytes(64));
|
||||
return $"v1.{tenantId:N}.{sessionId:N}.{Base64UrlEncoder.Encode(RandomNumberGenerator.GetBytes(64))}";
|
||||
}
|
||||
|
||||
public bool TryParseRefreshToken(string refreshToken, out RefreshTokenLocator locator)
|
||||
{
|
||||
locator = default;
|
||||
if (string.IsNullOrWhiteSpace(refreshToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var parts = refreshToken.Split('.', 4, StringSplitOptions.None);
|
||||
if (parts.Length != 4 || parts[0] != "v1" || parts[3].Length < 32 ||
|
||||
!Guid.TryParseExact(parts[1], "N", out var tenantId) ||
|
||||
!Guid.TryParseExact(parts[2], "N", out var sessionId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
locator = new RefreshTokenLocator(tenantId, sessionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
public string HashRefreshToken(string refreshToken)
|
||||
@@ -37,17 +57,19 @@ public sealed class SessionService(
|
||||
string? userAgent,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var refreshToken = GenerateRefreshToken();
|
||||
var session = new AuthSession
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
TenantId = membership.TenantId,
|
||||
UserId = userId,
|
||||
TokenHash = HashRefreshToken(refreshToken),
|
||||
TokenHash = string.Empty,
|
||||
Provider = provider,
|
||||
ExpiresAt = DateTimeOffset.UtcNow.AddDays(options.RefreshTokenDays),
|
||||
IpAddress = ipAddress,
|
||||
UserAgent = userAgent
|
||||
};
|
||||
var refreshToken = GenerateRefreshToken(session.TenantId, session.Id);
|
||||
session.TokenHash = HashRefreshToken(refreshToken);
|
||||
|
||||
dbContext.AuthSessions.Add(session);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user