-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from Star-Academy/feature/logout
feat: add logout api
- Loading branch information
Showing
11 changed files
with
147 additions
and
62 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Domain.Entities; | ||
|
||
namespace Application.Interfaces; | ||
|
||
public interface ITokenService | ||
{ | ||
string GenerateToken(AppUser user, string role); | ||
Task<bool> IsTokenInvalidatedAsync(string token); | ||
Task AddInvalidatedTokenAsync(string token); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Application.Interfaces; | ||
|
||
namespace Web.Middleware; | ||
|
||
public class TokenValidationMiddleware | ||
{ | ||
private readonly RequestDelegate _next; | ||
private readonly IServiceProvider _serviceProvider; | ||
|
||
public TokenValidationMiddleware(RequestDelegate next, IServiceProvider serviceProvider) | ||
{ | ||
_next = next; | ||
_serviceProvider = serviceProvider; | ||
} | ||
|
||
public async Task InvokeAsync(HttpContext context) | ||
{ | ||
// Create a scope to resolve scoped services | ||
using var scope = _serviceProvider.CreateScope(); | ||
var tokenService = scope.ServiceProvider.GetRequiredService<ITokenService>(); | ||
|
||
var authHeader = context.Request.Headers["Authorization"].FirstOrDefault(); | ||
if (authHeader != null && authHeader.StartsWith("Bearer ")) | ||
{ | ||
var token = authHeader.Substring("Bearer ".Length).Trim(); | ||
if (await tokenService.IsTokenInvalidatedAsync(token)) | ||
{ | ||
context.Response.StatusCode = StatusCodes.Status401Unauthorized; | ||
return; | ||
} | ||
} | ||
|
||
await _next(context); | ||
} | ||
} |
103 changes: 59 additions & 44 deletions
103
src/Web/Services/JwtGeneratorService.cs → src/Web/Services/TokenService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,60 @@ | ||
using System.IdentityModel.Tokens.Jwt; | ||
using System.Security.Claims; | ||
using Application.Interfaces; | ||
using Domain.Entities; | ||
using Microsoft.IdentityModel.Tokens; | ||
using Web.Identity; | ||
|
||
namespace Web.Services; | ||
|
||
public class JwtGeneratorService : IJwtGenerator | ||
{ | ||
private readonly IConfiguration _configuration; | ||
private readonly SymmetricSecurityKey _symmetricSecurityKey; | ||
public JwtGeneratorService(IConfiguration configuration) | ||
{ | ||
_configuration = configuration; | ||
_symmetricSecurityKey = new SymmetricSecurityKey( | ||
System.Text.Encoding.UTF8.GetBytes(_configuration["JwtSettings:Key"]) | ||
); | ||
} | ||
public string GenerateToken(AppUser user, string role) | ||
{ | ||
var claims = new List<Claim> | ||
{ | ||
new Claim(JwtRegisteredClaimNames.Sub, user.Email), | ||
new Claim(Claims.UserId, user.Id), | ||
new Claim(Claims.Role, role) | ||
}; | ||
|
||
var credentials = new SigningCredentials(_symmetricSecurityKey, SecurityAlgorithms.HmacSha512Signature); | ||
|
||
var tokenDescriptor = new SecurityTokenDescriptor | ||
{ | ||
Subject = new ClaimsIdentity(claims), | ||
Expires = DateTime.Now.AddHours(8), | ||
SigningCredentials = credentials, | ||
Issuer = _configuration["JwtSettings:Issuer"], | ||
Audience = _configuration["JwtSettings:Audience"] | ||
}; | ||
|
||
var tokenHandler = new JwtSecurityTokenHandler(); | ||
var token = tokenHandler.CreateToken(tokenDescriptor); | ||
return tokenHandler.WriteToken(token); | ||
} | ||
using System.Collections.Concurrent; | ||
using System.IdentityModel.Tokens.Jwt; | ||
using System.Security.Claims; | ||
using Application.Interfaces; | ||
using Domain.Entities; | ||
using Microsoft.IdentityModel.Tokens; | ||
using Web.Identity; | ||
|
||
namespace Web.Services; | ||
|
||
public class TokenService : ITokenService | ||
{ | ||
private readonly IConfiguration _configuration; | ||
private readonly SymmetricSecurityKey _symmetricSecurityKey; | ||
private static readonly ConcurrentDictionary<string, DateTime> _invalidatedTokens = new(); | ||
|
||
public TokenService(IConfiguration configuration) | ||
{ | ||
_configuration = configuration; | ||
_symmetricSecurityKey = new SymmetricSecurityKey( | ||
System.Text.Encoding.UTF8.GetBytes(_configuration["JwtSettings:Key"]) | ||
); | ||
} | ||
|
||
public string GenerateToken(AppUser user, string role) | ||
{ | ||
var claims = new List<Claim> | ||
{ | ||
new Claim(JwtRegisteredClaimNames.Sub, user.Email), | ||
new Claim(Claims.UserId, user.Id), | ||
new Claim(Claims.Role, role) | ||
}; | ||
|
||
var credentials = new SigningCredentials(_symmetricSecurityKey, SecurityAlgorithms.HmacSha512Signature); | ||
|
||
var tokenDescriptor = new SecurityTokenDescriptor | ||
{ | ||
Subject = new ClaimsIdentity(claims), | ||
Expires = DateTime.Now.AddHours(8), | ||
SigningCredentials = credentials, | ||
Issuer = _configuration["JwtSettings:Issuer"], | ||
Audience = _configuration["JwtSettings:Audience"] | ||
}; | ||
|
||
var tokenHandler = new JwtSecurityTokenHandler(); | ||
var token = tokenHandler.CreateToken(tokenDescriptor); | ||
return tokenHandler.WriteToken(token); | ||
} | ||
|
||
public Task<bool> IsTokenInvalidatedAsync(string token) | ||
{ | ||
return Task.FromResult(_invalidatedTokens.ContainsKey(token)); | ||
} | ||
|
||
public Task AddInvalidatedTokenAsync(string token) | ||
{ | ||
_invalidatedTokens[token] = DateTime.UtcNow; | ||
return Task.CompletedTask; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters