Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/#17-이미지-업로드-구현' into #17-이미지-업로드-구현
Browse files Browse the repository at this point in the history
  • Loading branch information
0BVer committed Apr 30, 2022
2 parents c0b0e14 + 23af74d commit a354468
Show file tree
Hide file tree
Showing 22 changed files with 317 additions and 318 deletions.
11 changes: 10 additions & 1 deletion backend/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'org.springframework.boot' version '2.6.5'
id 'org.springframework.boot' version '2.6.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.asciidoctor.convert' version '1.5.8'
id 'java'
Expand Down Expand Up @@ -54,9 +54,18 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.2'
implementation 'org.springframework.boot:spring-boot-starter-log4j2'


}
configurations {
all*.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
all*.exclude group: 'org.springframework.boot', module: 'logback-classic'
}

tasks.named('compileJava') {
inputs.files(tasks.named('processResources'))
}

bootRun {
mainClassName = 'com.hjjang.backend.BackendApplication'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.hjjang.backend.domain.user.controller;

import com.hjjang.backend.domain.user.dto.LoginRequest;
import com.hjjang.backend.domain.user.entity.RoleType;
import com.hjjang.backend.domain.user.entity.UserRefreshToken;
import com.hjjang.backend.domain.user.repository.UserRefreshTokenRepository;
Expand All @@ -13,7 +12,9 @@
import com.hjjang.backend.global.util.HeaderUtil;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
Expand All @@ -30,16 +31,8 @@ public class UserAuthController {
private final UserRefreshTokenRepository userRefreshTokenRepository;
private final UserAuthService userAuthService;

private final static long THREE_DAYS_MSEC = 259200000;
private final static String REFRESH_TOKEN = "refresh_token";

@PostMapping("/login")
public ApiResponse login(HttpServletRequest request, HttpServletResponse response,
@RequestBody LoginRequest loginRequest
) {
String token = userAuthService.login(request, response, loginRequest);
return ApiResponse.success("token", token);
}
private static final long THREE_DAYS_MSEC = 259200000;
private static final String REFRESH_TOKEN = "refresh_token";

@GetMapping("/refresh")
public ApiResponse refreshToken(HttpServletRequest request, HttpServletResponse response) {
Expand All @@ -55,31 +48,33 @@ public ApiResponse refreshToken(HttpServletRequest request, HttpServletResponse
if (claims == null) {
return ApiResponse.notExpiredTokenYet();
}

String userId = claims.getSubject();
String providerId = claims.getSubject();
RoleType roleType = RoleType.of(claims.get("role", String.class));

// refresh token
String refreshToken = CookieUtil.getCookie(request, REFRESH_TOKEN)
.map(Cookie::getValue)
.orElse((null));
.map(Cookie::getValue)
.orElse((null));
AuthToken authRefreshToken = tokenProvider.convertAuthToken(refreshToken);

if (authRefreshToken.validate()) {
return ApiResponse.invalidRefreshToken();
}

// userId, refresh token 으로 DB 확인
UserRefreshToken userRefreshToken = userRefreshTokenRepository.findByUserIdAndRefreshToken(userId, refreshToken);
// providerId, refresh token 으로 DB 확인
UserRefreshToken userRefreshToken = userRefreshTokenRepository.findByProviderIdAndRefreshToken(providerId,
refreshToken);
if (userRefreshToken == null) {
return ApiResponse.invalidRefreshToken();
}

Date now = new Date();
AuthToken newAccessToken = tokenProvider.createAuthToken(
userId, roleType.getCode(), new Date(now.getTime() + authProperties.getTokenProperties().getTokenExpireDate())
providerId, roleType.getCode(),
new Date(now.getTime() + authProperties.getTokenProperties().getTokenExpireDate())
);
userAuthService.reissueRefreshTokenIfValidTimeleft3days(request, response, userRefreshToken, authRefreshToken, now);
userAuthService.reissueRefreshTokenIfValidTimeleft3days(request, response, userRefreshToken, authRefreshToken,
now);

return ApiResponse.success("token", newAccessToken.getToken());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
package com.hjjang.backend.domain.user.controller;

import com.hjjang.backend.domain.user.entity.User;
import com.hjjang.backend.domain.user.service.UserService;
import com.hjjang.backend.global.dto.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.hjjang.backend.domain.user.dto.UserProfileDTO;
import com.hjjang.backend.domain.user.service.UserProfileService;
import com.hjjang.backend.global.dto.ApiResponse;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {

private final UserService userService;

@GetMapping
public ApiResponse getUser() {
org.springframework.security.core.userdetails.User principal = (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

User user = userService.getUser(principal.getUsername());
private final UserProfileService userProfileService;

return ApiResponse.success("user", user);
@GetMapping("/profile")
public ApiResponse getProfile() {
UserProfileDTO userProfile = userProfileService.getUserProfile();
return ApiResponse.success("userProfile", userProfile);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.hjjang.backend.domain.user.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserProfileDTO {

private String userNickname;

private String userImageUrl;

private String userEmail;

private Long userMannerTemperature;

private String userUnivName;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.time.LocalDateTime;

import static javax.persistence.EnumType.STRING;
import static javax.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

@Getter
Expand All @@ -22,8 +23,12 @@
public class User {

@Id
@Column(name = "id", nullable = false, length = 128)
private String id;
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", nullable = false)
private Long id;

@Column(name = "provider_id", nullable = false, length = 128)
private String providerId;

@Column(name = "nickname", nullable = false, length = 30)
private String nickName;
Expand Down Expand Up @@ -53,8 +58,8 @@ public class User {
private RoleType role;

@Builder
public User(String id, String nickName, String email, Long mannerTemperature, String imageUrl, Agreement isPushAgree, Long univId, RoleType role) {
this.id = id;
public User(String providerId, String nickName, String email, Long mannerTemperature, String imageUrl, Agreement isPushAgree, Long univId, RoleType role) {
this.providerId = providerId;
this.nickName = nickName;
this.email = email;
this.mannerTemperature = mannerTemperature;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.hjjang.backend.domain.user.entity;

import com.sun.istack.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

import static javax.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
Expand All @@ -22,20 +22,20 @@ public class UserRefreshToken {
@Column(name = "id", nullable = false)
private Long id;

@Column(name = "user_id", nullable = false, length = 64)
private String userId;
@Column(name = "provider_id", nullable = false, length = 64)
private String providerId;

@Column(name = "refresh_token", nullable = false, length = 256)
@NotNull
private String refreshToken;

@Builder
public UserRefreshToken(String userId, String refreshToken) {
this.userId = userId;
public UserRefreshToken(String providerId, String refreshToken) {
this.providerId = providerId;
this.refreshToken = refreshToken;
}

public void setRefreshToken(String refreshToken) {
public void reissueRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.hjjang.backend.domain.user.exception;

public class UserDoesNotExistException {
public UserDoesNotExistException() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import com.hjjang.backend.domain.user.entity.UserRefreshToken;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRefreshTokenRepository extends JpaRepository<UserRefreshToken,Long> {
UserRefreshToken findByUserId(String userId);
UserRefreshToken findByUserIdAndRefreshToken(String userId, String refreshToken);
public interface UserRefreshTokenRepository extends JpaRepository<UserRefreshToken, Long> {
UserRefreshToken findByProviderId(String providerId);

UserRefreshToken findByProviderIdAndRefreshToken(String providerId, String refreshToken);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import com.hjjang.backend.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, String> {
User findUserById(String Id);
import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findUserById(Long id);

Optional<User> findUserByProviderId(String providerId);
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
package com.hjjang.backend.domain.user.service;

import com.hjjang.backend.domain.user.dto.LoginRequest;
import com.hjjang.backend.domain.user.entity.RoleType;
import static com.hjjang.backend.global.config.security.repository.OAuth2AuthorizationRequestBasedOnCookieRepository.*;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.stereotype.Service;

import com.hjjang.backend.domain.user.entity.UserRefreshToken;
import com.hjjang.backend.domain.user.repository.UserRefreshTokenRepository;
import com.hjjang.backend.global.config.properties.AuthProperties;
import com.hjjang.backend.global.config.security.principal.UserPrincipal;
import com.hjjang.backend.global.config.security.token.AuthToken;
import com.hjjang.backend.global.config.security.token.AuthTokenProvider;
import com.hjjang.backend.global.util.CookieUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

import static com.hjjang.backend.global.config.security.repository.OAuth2AuthorizationRequestBasedOnCookieRepository.REFRESH_TOKEN;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
Expand All @@ -32,60 +29,8 @@ public class UserAuthService {
private final UserRefreshTokenRepository userRefreshTokenRepository;
private final static long THREE_DAYS_MSEC = 259200000;

public String login(HttpServletRequest request, HttpServletResponse response,
LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getId(),
loginRequest.getPassword()
)
);

String userId = loginRequest.getId();
SecurityContextHolder.getContext().setAuthentication(authentication);

Date now = new Date();
AuthToken accessToken = tokenProvider.createAuthToken(
userId,
((UserPrincipal) authentication.getPrincipal()).getRoleType().getCode(),
new Date(now.getTime() + authProperties.getTokenProperties().getTokenExpireDate())
);

long refreshTokenExpiry = authProperties.getTokenProperties().getRefreshTokenExpiry();
AuthToken refreshToken = tokenProvider.createAuthToken(
authProperties.getTokenProperties().getTokenSecretKey(),
new Date(now.getTime() + refreshTokenExpiry)
);

// userId refresh token 으로 DB 확인
UserRefreshToken userRefreshToken = userRefreshTokenRepository.findByUserId(userId);
if (userRefreshToken == null) {
// 없는 경우 새로 등록
userRefreshToken = new UserRefreshToken(userId, refreshToken.getToken());
userRefreshTokenRepository.saveAndFlush(userRefreshToken);
} else {
// DB에 refresh 토큰 업데이트
userRefreshToken.setRefreshToken(refreshToken.getToken());
}

int cookieMaxAge = (int) refreshTokenExpiry / 60;
CookieUtil.deleteCookie(request, response, REFRESH_TOKEN);
CookieUtil.addCookie(response, REFRESH_TOKEN, refreshToken.getToken(), cookieMaxAge);

return accessToken.getToken();
}

public AuthToken createAuthToken(String userId, RoleType roleType, Date expiredDate) {
Date now = new Date();
return tokenProvider.createAuthToken(
userId, roleType.getCode(),
new Date(now.getTime() + authProperties.getTokenProperties().getTokenExpireDate())
);
}


public void reissueRefreshTokenIfValidTimeleft3days(HttpServletRequest request, HttpServletResponse response,
UserRefreshToken userRefreshToken, AuthToken authRefreshToken, Date now) {
UserRefreshToken userRefreshToken, AuthToken authRefreshToken, Date now) {
long validTime = authRefreshToken.getTokenClaims().getExpiration().getTime() - now.getTime();

// refresh 토큰 기간이 3일 이하로 남은 경우, refresh 토큰 갱신
Expand All @@ -94,14 +39,14 @@ public void reissueRefreshTokenIfValidTimeleft3days(HttpServletRequest request,
long refreshTokenExpiry = authProperties.getTokenProperties().getRefreshTokenExpiry();

authRefreshToken = tokenProvider.createAuthToken(
authProperties.getTokenProperties().getTokenSecretKey(),
new Date(now.getTime() + refreshTokenExpiry)
authProperties.getTokenProperties().getTokenSecretKey(),
new Date(now.getTime() + refreshTokenExpiry)
);

// DB에 refresh 토큰 업데이트
userRefreshToken.setRefreshToken(authRefreshToken.getToken());
userRefreshToken.reissueRefreshToken(authRefreshToken.getToken());

int cookieMaxAge = (int) refreshTokenExpiry / 60;
int cookieMaxAge = (int)refreshTokenExpiry / 60;
CookieUtil.deleteCookie(request, response, REFRESH_TOKEN);
CookieUtil.addCookie(response, REFRESH_TOKEN, authRefreshToken.getToken(), cookieMaxAge);
}
Expand Down
Loading

0 comments on commit a354468

Please sign in to comment.