Skip to content

Commit

Permalink
Merge pull request #132 from PawWithU/feat/131-logout-api
Browse files Browse the repository at this point in the history
[Feature] 이동봉사자/중개 로그아웃 API 구현
  • Loading branch information
hojeong2747 authored Nov 21, 2023
2 parents 2aa40f8 + 5ccbf2f commit 9da0179
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package com.pawwithu.connectdog.domain.auth.controller;

import com.pawwithu.connectdog.domain.auth.dto.request.RefreshTokenRequest;
import com.pawwithu.connectdog.domain.auth.service.AuthService;
import com.pawwithu.connectdog.domain.oauth.dto.response.LoginResponse;
import com.pawwithu.connectdog.error.dto.ErrorResponse;
import com.pawwithu.connectdog.jwt.service.JwtService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -22,6 +28,7 @@
public class AuthController {

private final JwtService jwtService;
private final AuthService authService;

@Operation(summary = "토큰 재발행", description = "AccessToken, RefreshToken 재발행 합니다.",
responses = {@ApiResponse(responseCode = "200", description = "토큰 재발행 성공")
Expand All @@ -37,4 +44,30 @@ public ResponseEntity<LoginResponse> reIssueToken(@Valid @RequestBody RefreshTok
return ResponseEntity.ok(response);
}

@Operation(summary = "이동봉사자 - 로그아웃", description = "이동봉사자가 로그아웃을 합니다.",
security = {@SecurityRequirement(name = "bearer-key") },
responses = {@ApiResponse(responseCode = "200", description = "이동봉사자 로그아웃 성공")
, @ApiResponse(responseCode = "400"
, description = "T1, 토큰이 존재하지 않습니다. \t\n M1, 해당 이동봉사자를 찾을 수 없습니다. \t\n M4, 해당 토큰에서 ROLE_NAME을 찾을 수 없습니다."
, content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@DeleteMapping("/volunteers/logout")
public ResponseEntity<Void> volunteersLogout(HttpServletRequest request, @AuthenticationPrincipal UserDetails loginUser) {
authService.volunteersLogout(request, loginUser.getUsername());
return ResponseEntity.noContent().build();
}

@Operation(summary = "로그아웃", description = "로그아웃을 합니다.",
security = {@SecurityRequirement(name = "bearer-key") },
responses = {@ApiResponse(responseCode = "200", description = "로그아웃 성공")
, @ApiResponse(responseCode = "400"
, description = "T1, 토큰이 존재하지 않습니다. \t\n M2, 해당 이동봉사 중개를 찾을 수 없습니다. \t\n M4, 해당 토큰에서 ROLE_NAME을 찾을 수 없습니다."
, content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@DeleteMapping("/intermediaries/logout")
public ResponseEntity<Void> intermediariesLogout(HttpServletRequest request, @AuthenticationPrincipal UserDetails loginUser) {
authService.intermediariesLogout(request, loginUser.getUsername());
return ResponseEntity.noContent().build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
import com.pawwithu.connectdog.domain.auth.dto.request.IntermediarySignUpRequest;
import com.pawwithu.connectdog.domain.auth.dto.request.SocialSignUpRequest;
import com.pawwithu.connectdog.domain.auth.dto.request.VolunteerSignUpRequest;
import com.pawwithu.connectdog.domain.fcm.repository.IntermediaryFcmRepository;
import com.pawwithu.connectdog.domain.fcm.repository.VolunteerFcmRepository;
import com.pawwithu.connectdog.domain.intermediary.entity.Intermediary;
import com.pawwithu.connectdog.domain.intermediary.repository.IntermediaryRepository;
import com.pawwithu.connectdog.domain.volunteer.entity.Volunteer;
import com.pawwithu.connectdog.domain.volunteer.entity.VolunteerRole;
import com.pawwithu.connectdog.domain.volunteer.repository.VolunteerRepository;
import com.pawwithu.connectdog.error.exception.custom.BadRequestException;
import com.pawwithu.connectdog.jwt.service.JwtService;
import com.pawwithu.connectdog.util.RedisUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
Expand All @@ -29,6 +34,10 @@ public class AuthService {
private final IntermediaryRepository intermediaryRepository;
private final PasswordEncoder passwordEncoder;
private final FileService fileService;
private final JwtService jwtService;
private final RedisUtil redisUtil;
private final VolunteerFcmRepository volunteerFcmRepository;
private final IntermediaryFcmRepository intermediaryFcmRepository;

public void volunteerSignUp(VolunteerSignUpRequest request) {

Expand Down Expand Up @@ -80,4 +89,24 @@ public void volunteerSocialSignUp(String email, SocialSignUpRequest socialSignUp
Boolean isOptionAgr = socialSignUpRequest.isOptionAgr();
volunteer.updateSocialVolunteer(nickname, VolunteerRole.VOLUNTEER, profileImageNum, isOptionAgr); // GUEST -> VOLUNTEER
}

public void volunteersLogout(HttpServletRequest request, String email) {
String accessToken = jwtService.extractAccessToken(request).orElseThrow(() -> new BadRequestException(TOKEN_NOT_EXIST));
Volunteer volunteer = volunteerRepository.findByEmail(email).orElseThrow(() -> new BadRequestException(VOLUNTEER_NOT_FOUND));
String roleName = jwtService.extractRoleName(accessToken).orElseThrow(() -> new BadRequestException(NOT_FOUND_ROLE_NAME));

redisUtil.delete(roleName, volunteer.getId());
volunteerFcmRepository.deleteByVolunteerId(volunteer.getId());
redisUtil.setBlackList(accessToken, "accessToken", jwtService.getAccessTokenExpirationPeriod());
}

public void intermediariesLogout(HttpServletRequest request, String email) {
String accessToken = jwtService.extractAccessToken(request).orElseThrow(() -> new BadRequestException(TOKEN_NOT_EXIST));
Intermediary intermediary = intermediaryRepository.findByEmail(email).orElseThrow(() -> new BadRequestException(INTERMEDIARY_NOT_FOUND));
String roleName = jwtService.extractRoleName(accessToken).orElseThrow(() -> new BadRequestException(NOT_FOUND_ROLE_NAME));

redisUtil.delete(roleName, intermediary.getId());
intermediaryFcmRepository.deleteByIntermediaryId(intermediary.getId());
redisUtil.setBlackList(accessToken, "accessToken", jwtService.getAccessTokenExpirationPeriod());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
import org.springframework.data.jpa.repository.JpaRepository;

public interface IntermediaryFcmRepository extends JpaRepository<IntermediaryFcm, Long> {
void deleteByIntermediaryId(Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
import org.springframework.data.jpa.repository.JpaRepository;

public interface VolunteerFcmRepository extends JpaRepository<VolunteerFcm, Long> {
void deleteByVolunteerId(Long id);
}
1 change: 1 addition & 0 deletions src/main/java/com/pawwithu/connectdog/error/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public enum ErrorCode {
VOLUNTEER_NOT_FOUND("M1", "해당 이동봉사자를 찾을 수 없습니다."), // Member -> M (이동봉사자, 이동봉사 중개 통일)
INTERMEDIARY_NOT_FOUND("M2", "해당 이동봉사 중개를 찾을 수 없습니다."),
INVALID_ROLE_NAME("M3", "해당 ROLE_NAME을 가진 이동봉사자/중개를 찾을 수 없습니다."),
NOT_FOUND_ROLE_NAME("M4", "해당 토큰에서 ROLE_NAME을 찾을 수 없습니다."),

TOKEN_NOT_EXIST("T1", "토큰이 존재하지 않습니다."),
TOKEN_IS_EXPIRED("T2", "만료된 토큰입니다."),
Expand Down

0 comments on commit 9da0179

Please sign in to comment.