Skip to content

Commit

Permalink
Merge pull request #55 from project-lyrics/SCRUM-189
Browse files Browse the repository at this point in the history
device_id 검사 로직 추가
  • Loading branch information
jinkonu authored Nov 8, 2024
2 parents 32c8030 + fb08d2b commit 233724c
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,21 @@ public class AuthController {

@PostMapping("/sign-in")
public ResponseEntity<AuthTokenResponse> signIn(
@RequestBody @Valid AuthSignInRequest request
@RequestBody @Valid AuthSignInRequest request,
@RequestHeader("Device-Id") String deviceId
) {
return ResponseEntity
.status(HttpStatus.OK)
.body(authCommandService.signIn(request));
.body(authCommandService.signIn(request, deviceId));
}

@PostMapping("/sign-up")
public ResponseEntity<AuthTokenResponse> signUp(
@RequestBody @Valid AuthSignUpRequest request
@RequestBody @Valid AuthSignUpRequest request,
@RequestHeader("Device-Id") String deviceId
) {
return ResponseEntity
.ok(authCommandService.signUp(request));
.ok(authCommandService.signUp(request, deviceId));
}

@PostMapping("/token")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.projectlyrics.server.domain.auth.authentication.interceptor;

import com.projectlyrics.server.domain.auth.exception.NotRegisteredDeviceException;
import com.projectlyrics.server.domain.auth.repository.AuthRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.HandlerInterceptor;

@Profile({"dev", "local"})
@Component
@Transactional
@RequiredArgsConstructor
public class DeviceIdInterceptor implements HandlerInterceptor {

private final AuthRepository authRepository;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (included(request)) {
authRepository.findByDeviceId(request.getHeader("Device-Id"))
.orElseThrow(NotRegisteredDeviceException::new);
}

return true;
}

private boolean included(HttpServletRequest request) {
String requestURI = request.getRequestURI();
return !requestURI.matches("/api/v1/auth/sign-in") &&
!requestURI.matches("/api/v1/auth/sign-up");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,31 @@ public class Auth {
private AuthProvider authProvider;
@Indexed
private String refreshToken;
@Indexed
private String deviceId;

private Auth(
String socialId,
AuthProvider authProvider,
String refreshToken
String refreshToken,
String deviceId
) {
this.socialId = socialId;
this.authProvider = authProvider;
this.refreshToken = refreshToken;
this.deviceId = deviceId;
}

public static Auth create(SocialInfo socialInfo, String refreshToken) {
public static Auth create(
SocialInfo socialInfo,
String refreshToken,
String deviceId
) {
return new Auth(
socialInfo.getSocialId(),
socialInfo.getAuthProvider(),
refreshToken
refreshToken,
deviceId
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.projectlyrics.server.domain.auth.exception;

import com.projectlyrics.server.domain.common.message.ErrorCode;
import com.projectlyrics.server.global.exception.FeelinException;

public class NotRegisteredDeviceException extends FeelinException {

public NotRegisteredDeviceException() {
super(ErrorCode.NOT_REGISTERED_DEVICE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
public interface AuthRepository extends CrudRepository<Auth, String> {

Optional<Auth> findByRefreshToken(String refreshToken);
Optional<Auth> findByDeviceId(String deviceId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ public class AuthCommandService {
private final LikeCommandRepository likeCommandRepository;
private final NotificationCommandRepository notificationCommandRepository;

public AuthTokenResponse signUp(AuthSignUpRequest request) {
public AuthTokenResponse signUp(AuthSignUpRequest request, String deviceId) {
SocialInfo socialInfo = authQueryService.getSocialInfo(AuthGetSocialInfo.from(request));
checkIfAlreadyExists(socialInfo);

User user = userCommandRepository.save(User.create(UserCreate.of(socialInfo, request)));

AuthToken authToken = issueAndSaveToken(user);
AuthToken authToken = issueAndSaveToken(user, deviceId);
return AuthTokenResponse.of(authToken, user.getId());
}

Expand All @@ -60,12 +60,12 @@ else if (userQueryRepository.existsBySocialInfoAndForceDelete(socialInfo)) {
}
}

public AuthTokenResponse signIn(AuthSignInRequest request) {
public AuthTokenResponse signIn(AuthSignInRequest request, String deviceId) {
SocialInfo socialInfo = authQueryService.getSocialInfo(AuthGetSocialInfo.from(request));
User user = userQueryRepository.findBySocialIdAndAuthProvider(socialInfo.getSocialId(), socialInfo.getAuthProvider())
.orElseThrow(UserNotFoundException::new);

AuthToken authToken = issueAndSaveToken(user);
AuthToken authToken = issueAndSaveToken(user, deviceId);
return AuthTokenResponse.of(authToken, user.getId());
}

Expand All @@ -75,13 +75,13 @@ public AuthTokenResponse reissueToken(String refreshToken) {
User user = userQueryRepository.findBySocialIdAndAuthProvider(auth.getSocialId(), auth.getAuthProvider())
.orElseThrow(UserNotFoundException::new);

AuthToken authToken = issueAndSaveToken(user);
AuthToken authToken = issueAndSaveToken(user, auth.getDeviceId());
return AuthTokenResponse.of(authToken, user.getId());
}

private AuthToken issueAndSaveToken(User user) {
private AuthToken issueAndSaveToken(User user, String deviceId) {
AuthToken authToken = jwtProvider.issueTokens(user.getId(), user.getNickname().getValue(), user.getRole());
authRepository.save(Auth.create(user.getSocialInfo(), authToken.refreshToken()));
authRepository.save(Auth.create(user.getSocialInfo(), authToken.refreshToken(), deviceId));

return authToken;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public enum ErrorCode {
INVALID_TOKEN_PREFIX(HttpStatus.BAD_REQUEST, "01009", "Bearer 인증 형식이 아닙니다."),
INVALID_SOCIAL_TOKEN(HttpStatus.UNAUTHORIZED, "01010", "유효하지 않은 소셜 인증 토큰입니다."),
AUTH_NOT_FOUND(HttpStatus.NOT_FOUND, "01011", "해당 인증 정보를 찾을 수 없습니다."),
NOT_REGISTERED_DEVICE(HttpStatus.NOT_FOUND, "01012", "타 기기에서 로그인했거나 등록되지 않은 기기입니다."),

// User
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "02000", "해당 유저가 존재하지 않습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,42 @@
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Objects;

@RequiredArgsConstructor
@Repository
public class JdbcSongCommandRepository implements SongCommandRepository {

private final JdbcTemplate jdbcTemplate;
private final String insertQuery = "INSERT INTO songs (id, artist_id, spotify_id, name, release_date, album_name, image_url) VALUES (?, ?, ?, ?, ?, ?, ?)";
private final String insertQuery = "INSERT INTO songs (artist_id, spotify_id, name, release_date, album_name, image_url) VALUES (?, ?, ?, ?, ?, ?)";
private final String insertQueryWithId = "INSERT INTO songs (id, artist_id, spotify_id, name, release_date, album_name, image_url) VALUES (?, ?, ?, ?, ?, ?, ?)";

@Override
public Song save(Song song) {
jdbcTemplate.update(
insertQuery,
song.getId(),
song.getArtist().getId(),
song.getSpotifyId(),
song.getName(),
song.getReleaseDate(),
song.getAlbumName(),
song.getImageUrl()
);
if (Objects.nonNull(song.getId())) {
jdbcTemplate.update(
insertQueryWithId,
song.getId(),
song.getArtist().getId(),
song.getSpotifyId(),
song.getName(),
song.getReleaseDate(),
song.getAlbumName(),
song.getImageUrl()
);
}

else {
jdbcTemplate.update(
insertQuery,
song.getArtist().getId(),
song.getSpotifyId(),
song.getName(),
song.getReleaseDate(),
song.getAlbumName(),
song.getImageUrl()
);
}

return song;
}
Expand All @@ -38,13 +54,12 @@ public void saveAll(List<Song> songs) {
songs,
songs.size(),
(ps, song) -> {
ps.setLong(1, song.getId());
ps.setLong(2, song.getArtist().getId());
ps.setString(3, song.getSpotifyId());
ps.setString(4, song.getName());
ps.setDate(5, java.sql.Date.valueOf(song.getReleaseDate()));
ps.setString(6, song.getAlbumName());
ps.setString(7, song.getImageUrl());
ps.setLong(1, song.getArtist().getId());
ps.setString(2, song.getSpotifyId());
ps.setString(3, song.getName());
ps.setDate(4, java.sql.Date.valueOf(song.getReleaseDate()));
ps.setString(5, song.getAlbumName());
ps.setString(6, song.getImageUrl());
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

import com.projectlyrics.server.domain.auth.authentication.AuthArgumentResolver;
import com.projectlyrics.server.domain.auth.authentication.interceptor.AuthInterceptor;
import com.projectlyrics.server.domain.auth.authentication.interceptor.DeviceIdInterceptor;
import com.projectlyrics.server.domain.auth.authentication.interceptor.SlackInterceptor;
import com.projectlyrics.server.domain.auth.authentication.interceptor.AdminInterceptor;
import com.projectlyrics.server.global.converter.ProfileCharacterConverter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;
import java.util.Objects;

@Configuration
@RequiredArgsConstructor
Expand All @@ -23,6 +26,9 @@ public class WebConfig implements WebMvcConfigurer {
private final AdminInterceptor adminInterceptor;
private final SlackInterceptor slackInterceptor;

@Autowired(required = false)
private DeviceIdInterceptor deviceIdInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
Expand All @@ -33,6 +39,13 @@ public void addInterceptors(InterceptorRegistry registry) {
.excludePathPatterns("/api/v1/auth/token")
.excludePathPatterns("/api/v1/slack/interactive");

if (Objects.nonNull(deviceIdInterceptor)) {
registry.addInterceptor(deviceIdInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns("/api/v1/auth/sign-in")
.addPathPatterns("/api/v1/auth/sign-up");
}

registry.addInterceptor(adminInterceptor)
.addPathPatterns("/api/v1/artists/**")
.addPathPatterns("/api/v1/notifications/public")
Expand Down
Loading

0 comments on commit 233724c

Please sign in to comment.