Fix refreshtoken api
This commit is contained in:
parent
fd5f456a31
commit
ec150cd642
13 changed files with 144 additions and 6 deletions
|
|
@ -6,7 +6,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||
|
||||
import br.com.rayankonecny.hdcommoslib.models.exceptions.StandardError;
|
||||
import br.com.rayankonecny.hdcommoslib.models.requests.AuthenticateRequest;
|
||||
import br.com.rayankonecny.hdcommoslib.models.requests.RefreshTokenRequest;
|
||||
import br.com.rayankonecny.hdcommoslib.models.responses.AuthenticationResponse;
|
||||
import br.com.rayankonecny.hdcommoslib.models.responses.RefreshTokenResponse;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
|
|
@ -32,4 +35,16 @@ public interface AuthController {
|
|||
@Valid
|
||||
final AuthenticateRequest requests) throws Exception;
|
||||
|
||||
@Operation(summary = "Refresh token")
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "Token refreshed", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = RefreshTokenResponse.class))),
|
||||
@ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))),
|
||||
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))),
|
||||
@ApiResponse(responseCode = "404", description = "Username not found", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))),
|
||||
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))) })
|
||||
@PostMapping("/refreshtoken")
|
||||
ResponseEntity<RefreshTokenResponse> refreshToken(@Valid
|
||||
@RequestBody
|
||||
final RefreshTokenRequest refreshToken) throws Exception;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,13 @@ import org.springframework.http.ResponseEntity;
|
|||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import br.com.rayankonecny.authserviceapi.controllers.AuthController;
|
||||
import br.com.rayankonecny.authserviceapi.models.RefreshToken;
|
||||
import br.com.rayankonecny.authserviceapi.services.AuthService;
|
||||
import br.com.rayankonecny.authserviceapi.services.RefreshTokenService;
|
||||
import br.com.rayankonecny.hdcommoslib.models.requests.AuthenticateRequest;
|
||||
import br.com.rayankonecny.hdcommoslib.models.requests.RefreshTokenRequest;
|
||||
import br.com.rayankonecny.hdcommoslib.models.responses.AuthenticationResponse;
|
||||
import br.com.rayankonecny.hdcommoslib.models.responses.RefreshTokenResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
|
|
@ -15,6 +19,7 @@ import lombok.RequiredArgsConstructor;
|
|||
public class AuthControllerImpl implements AuthController {
|
||||
|
||||
private final AuthService authService;
|
||||
private final RefreshTokenService refreshService;
|
||||
|
||||
@Override
|
||||
public ResponseEntity<AuthenticationResponse> authenticate(@Valid
|
||||
|
|
@ -23,4 +28,10 @@ public class AuthControllerImpl implements AuthController {
|
|||
return ResponseEntity.ok(authService.authenticate(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<RefreshTokenResponse> refreshToken(@Valid
|
||||
RefreshTokenRequest request) throws Exception {
|
||||
return ResponseEntity.ok().body(refreshService.refreshToken(request.refreshToken()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
package br.com.rayankonecny.authserviceapi.models;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@Document
|
||||
public class RefreshToken {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
private String username;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime expiresAt;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package br.com.rayankonecny.authserviceapi.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import br.com.rayankonecny.authserviceapi.models.RefreshToken;
|
||||
|
||||
@Repository
|
||||
public interface RefreshTokenRepository extends MongoRepository<RefreshToken, String> {
|
||||
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import org.springframework.security.authentication.BadCredentialsException;
|
|||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import br.com.rayankonecny.authserviceapi.models.RefreshToken;
|
||||
import br.com.rayankonecny.authserviceapi.utils.JWTUtils;
|
||||
import br.com.rayankonecny.hdcommoslib.models.requests.AuthenticateRequest;
|
||||
import br.com.rayankonecny.hdcommoslib.models.responses.AuthenticationResponse;
|
||||
|
|
@ -15,6 +16,7 @@ import lombok.RequiredArgsConstructor;
|
|||
public class AuthService {
|
||||
|
||||
private final UserDetailsServiceImpl userDetailsService;
|
||||
private final RefreshTokenService refreshTokenService;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final JWTUtils jwtUtils;
|
||||
|
||||
|
|
@ -27,7 +29,8 @@ public class AuthService {
|
|||
}
|
||||
|
||||
String token = jwtUtils.generateToken(user);
|
||||
RefreshToken refresh = refreshTokenService.save(user.getUsername());
|
||||
|
||||
return new AuthenticationResponse(token,user.getUsername());
|
||||
return new AuthenticationResponse(token, refresh.getId(), user.getUsername());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
package br.com.rayankonecny.authserviceapi.services;
|
||||
|
||||
public class BadCredentialsExceptionion {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package br.com.rayankonecny.authserviceapi.services;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import br.com.rayankonecny.authserviceapi.models.RefreshToken;
|
||||
import br.com.rayankonecny.authserviceapi.repository.RefreshTokenRepository;
|
||||
import br.com.rayankonecny.authserviceapi.security.UserDetailsDTO;
|
||||
import br.com.rayankonecny.authserviceapi.utils.JWTUtils;
|
||||
import br.com.rayankonecny.hdcommoslib.models.exceptions.RefreshTokenExpired;
|
||||
import br.com.rayankonecny.hdcommoslib.models.exceptions.ResourceNotFoundException;
|
||||
import br.com.rayankonecny.hdcommoslib.models.responses.RefreshTokenResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import static java.time.LocalDateTime.now;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RefreshTokenService {
|
||||
|
||||
@Value("${jwt.expiration-sec.refresh-token}")
|
||||
private Long refreshTokenExpirationSec;
|
||||
|
||||
private final RefreshTokenRepository repository;
|
||||
private final UserDetailsService userDetail;
|
||||
private final JWTUtils jwtUtils;
|
||||
|
||||
public RefreshToken save(final String username) {
|
||||
return repository.save(RefreshToken.builder().id(UUID.randomUUID().toString())
|
||||
.expiresAt(now().plusSeconds(refreshTokenExpirationSec)).username(username).build());
|
||||
}
|
||||
|
||||
public RefreshTokenResponse refreshToken(final String refreshTokenId) {
|
||||
final var refreshToken = repository.findById(refreshTokenId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Refresh token not found. Id: " + refreshTokenId));
|
||||
|
||||
if (refreshToken.getExpiresAt().isBefore((now()))) {
|
||||
throw new RefreshTokenExpired("Refresh token expired. Id: " + refreshTokenId);
|
||||
}
|
||||
|
||||
return new RefreshTokenResponse(
|
||||
jwtUtils.generateToken((UserDetailsDTO) userDetail.loadUserByUsername(refreshToken.getUsername())));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -9,3 +9,4 @@ spring:
|
|||
enabled: false
|
||||
jwt.secret: "IHf3Yua/byvtA+iIcGWmkrLvpKEXTb5ClkXaZ0VDmYbr/6b1otCs38x68bidvZLAOB7anUtVQlCid6YDULO5XA=="
|
||||
jwt.expiration: 120000
|
||||
jwt.expiration-sec.refresh-token: 3600
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package br.com.rayankonecny.hdcommoslib.models.exceptions;
|
||||
|
||||
public class RefreshTokenExpired extends RuntimeException {
|
||||
public RefreshTokenExpired(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package br.com.rayankonecny.hdcommoslib.models.requests;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
public record RefreshTokenRequest(
|
||||
@Size(min = 16, max = 30, message = "Refresh token must be between 16 and 30 characters")
|
||||
@NotBlank(message = "Refresh token is required")
|
||||
String refreshToken
|
||||
) {
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import lombok.Builder;
|
|||
@Builder
|
||||
public record AuthenticationResponse(
|
||||
String token,
|
||||
String refreshToken,
|
||||
String type
|
||||
) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
package br.com.rayankonecny.hdcommoslib.models.responses;
|
||||
|
||||
public record RefreshTokenResponse(String refreshToken) {}
|
||||
10
rest.http
10
rest.http
|
|
@ -44,4 +44,14 @@ Accept: application/json
|
|||
{
|
||||
"email": "rayanvix@gmail.com",
|
||||
"password": "123456"
|
||||
}
|
||||
|
||||
|
||||
POST http://175.15.15.91:8080/auth/refresh-token
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
# Authorization: Bearer {{token}}
|
||||
|
||||
{
|
||||
"refreshToken": "73b32ec3-9933-4a60-ae06-b23c965dd1b2"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue