Skip to content

Instantly share code, notes, and snippets.

@wellingtonjhn
Last active July 18, 2018 01:16
Show Gist options
  • Select an option

  • Save wellingtonjhn/5d0691d91b8696d50e356aa96ab749ff to your computer and use it in GitHub Desktop.

Select an option

Save wellingtonjhn/5d0691d91b8696d50e356aa96ab749ff to your computer and use it in GitHub Desktop.
Authentication Handler - JWT + RefreshToken
public class Authenticate : Request<Response>
{
public string Email { get; }
public string Password { get; }
public string GrantType { get; }
public string RefreshToken { get; }
public Authenticate(string grantType, string email, string password, string refreshToken)
{
Validate(grantType, email, password, refreshToken);
GrantType = grantType;
Email = email;
Password = password;
RefreshToken = refreshToken;
}
private void Validate(string grantType, string email, string password, string refreshToken)
{
AddNotifications(new Contract()
.Requires()
.IsNotNullOrEmpty(grantType, nameof(grantType), "O tipo de autenticação não pode ficar vazio"));
if (!string.IsNullOrEmpty(grantType))
{
if (grantType.Equals("password"))
{
AddNotifications(new Contract()
.Requires()
.IsEmail(email, nameof(email), "E-mail inválido")
.IsNotNullOrEmpty(password, nameof(password), "A senha não pode ficar vazia"));
}
else if (grantType.Equals("refresh_token"))
{
AddNotifications(new Contract()
.Requires()
.IsNotNullOrEmpty(refreshToken, nameof(refreshToken), "O refresh token não pode ficar vazio"));
}
else
{
AddNotification(new Notification(nameof(grantType), "Tipo de autenticação inválido"));
}
}
}
}
public class AuthenticateHandler : IRequestHandler<Authenticate, Response>
{
private readonly IJwtService _jwtService;
private readonly IUserRepository _userRepository;
private readonly IRefreshTokenRepository _refreshTokenRepository;
private Response _response;
public AuthenticateHandler(
IJwtService jwtService,
IUserRepository userRepository,
IRefreshTokenRepository refreshTokenRepository)
{
_jwtService = jwtService;
_userRepository = userRepository;
_refreshTokenRepository = refreshTokenRepository;
}
public async Task<Response> Handle(Authenticate request, CancellationToken cancellationToken)
{
_response = new Response();
User user = null;
if (request.GrantType.Equals("password"))
{
user = await HandleUserAuthentication(request);
}
else if (request.GrantType.Equals("refresh_token"))
{
user = await HandleRefreshToken(request);
}
if (_response.HasMessages || user == null)
{
return _response;
}
await HandleJwt(user);
return _response;
}
private async Task HandleJwt(User user)
{
var jwt = _jwtService.CreateJsonWebToken(user);
await _refreshTokenRepository.Save(jwt.RefreshToken);
_response.AddValue(new
{
access_token = jwt.AccessToken,
refresh_token = jwt.RefreshToken.Token,
token_type = jwt.TokenType,
expires_in = jwt.ExpiresIn
});
}
private async Task<User> HandleUserAuthentication(Authenticate request)
{
var encodedPassword = new Password(request.Password).Encoded;
var user = await _userRepository.Authenticate(request.Email, encodedPassword);
if (user == null)
{
_response.AddNotification(new Notification("user", "Usuário ou senha inválidos"));
}
return user;
}
private async Task<User> HandleRefreshToken(Authenticate request)
{
var token = await _refreshTokenRepository.Get(request.RefreshToken);
if (token == null)
{
_response.AddNotification(new Notification(nameof(request.RefreshToken), "Refresh Token inválido"));
}
else if (token.ExpirationDate < DateTime.Now)
{
_response.AddNotification(new Notification(nameof(request.RefreshToken), "Refresh Token expirado"));
}
if (_response.HasMessages)
{
return null;
}
return await _userRepository.Get(token.Username);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment