Skip to content

Commit

Permalink
[Refact]: 비밀번호 인코딩 위치 변경
Browse files Browse the repository at this point in the history
  • Loading branch information
momnpa333 committed Jul 7, 2024
1 parent 2e229a1 commit bdac9c2
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,24 @@
@RequiredArgsConstructor
@RestController
public class AdminController {

private final AuthService authService;
private final ChallengeGroupService challengeGroupService;
private final BCryptPasswordEncoder passwordEncoder;

@ResponseStatus(HttpStatus.CREATED)
@Operation(summary= "매니저 등록", description = "매니저를 등록한다.")
@Operation(summary = "매니저 등록", description = "매니저를 등록한다.")
@PostMapping("/api/admin/auth/manager")
public ApiResponse<Void> createManager(@RequestBody @Valid AuthReq.EmailSignupRequest request) {
authService.createManager(request.toCommand()
.changePassword(passwordEncoder.encode(request.password())));
authService.createManager(request.toCommand());
return ApiResponse.success(null, "매니저 등록 성공");
}

@ResponseStatus(HttpStatus.CREATED)
@Operation(summary = "챌린지 그룹 생성", description = "챌린지 그룹과 해당하는 챌린지를 생성합니다")
@PostMapping("/api/admin/challengeGroups")
public ApiResponse<Void> createChallengeGroup(@RequestBody @Valid AdminReq.CreateChallengeGroupRequest request) {
public ApiResponse<Void> createChallengeGroup(
@RequestBody @Valid AdminReq.CreateChallengeGroupRequest request) {
challengeGroupService.createChallengeGroup(request.toCommand());
return ApiResponse.success(null, "챌린지 그룹 생성 성공");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,33 @@
@RequiredArgsConstructor
@RestController
public class AuthController {

private final AuthService authService;
private final BCryptPasswordEncoder passwordEncoder;

@Operation(summary = "oauth2 로그인", description = "oauth2 code를 이용하여 로그인한다.")
@PostMapping("/api/auth/oauth2")
public ApiResponse<AuthRes.LoginResponse> oauth2(@RequestBody @Valid AuthReq.OAuth2LoginRequest request) {
Pair<JwtToken,UserModel> pair = authService.oAuth2LoginOrSignup(request.provider(), request.code(), request.state());
public ApiResponse<AuthRes.LoginResponse> oauth2(
@RequestBody @Valid AuthReq.OAuth2LoginRequest request) {
Pair<JwtToken, UserModel> pair = authService.oAuth2LoginOrSignup(request.provider(),
request.code(), request.state());
var response = AuthRes.LoginResponse.from(pair.getFirst(), pair.getSecond());
return ApiResponse.success(response);
}

@Operation(summary = "이메일 회원가입", description = "이메일 회원가입을 한다.")
@PostMapping("/api/auth/signup")
public ApiResponse<AuthRes.LoginResponse> signup(@RequestBody @Valid AuthReq.EmailSignupRequest request) {
Pair<JwtToken, UserModel> pair = authService.signup(
request.toCommand()
.changePassword(passwordEncoder.encode(request.password()))
);
public ApiResponse<AuthRes.LoginResponse> signup(
@RequestBody @Valid AuthReq.EmailSignupRequest request) {
Pair<JwtToken, UserModel> pair = authService.signup(request.toCommand());
var response = AuthRes.LoginResponse.from(pair.getFirst(), pair.getSecond());
return ApiResponse.success(response);
}

@Operation(summary = "로그인", description = "로그인한다.")
@PostMapping("/api/auth/login")
public ApiResponse<AuthRes.LoginResponse> login(@RequestBody @Valid AuthReq.EmailLoginRequest request) {
public ApiResponse<AuthRes.LoginResponse> login(
@RequestBody @Valid AuthReq.EmailLoginRequest request) {
Pair<JwtToken, UserModel> pair = authService.login(request.email(), request.password());
var response = AuthRes.LoginResponse.from(pair.getFirst(), pair.getSecond());
return ApiResponse.success(response);
Expand All @@ -52,9 +54,9 @@ public ApiResponse<AuthRes.LoginResponse> login(@RequestBody @Valid AuthReq.Emai
@Operation(summary = "액세스 토큰 재발급", description = "리프레시 토큰을 이용하여 액세스 토큰을 재발급한다.")
@PostMapping("/api/auth/refresh")
public ApiResponse<AuthRes.AccessTokenResponse> refresh(
@RequestHeader("Authorization") String authorization
@RequestHeader("Authorization") String authorization
) {
if(authorization == null || !authorization.startsWith("Bearer ")) {
if (authorization == null || !authorization.startsWith("Bearer ")) {
throw new IllegalArgumentException("Bearer 토큰이 필요합니다.");
}
String rawToken = authorization.substring("Bearer ".length());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,31 @@
@Service
@RequiredArgsConstructor
public class AuthService {

private final List<OAuth2Client> oAuth2Clients;
private final BCryptPasswordEncoder passwordEncoder;
private final JwtUtils jwtUtils;
private final UserReader userReader;
private final UserStore userStore;

/**
* OAuth2 로그인 또는 회원가입 <br>
* [state]는 nullable한 입력 값이다.<br>
* 1. OAuth2Client를 이용해 해당 provider로부터 유저정보를 가져옴
* 2. authToken으로 유저를 찾거나 없으면 회원가입
* 3. 토큰 발급, 유저정보 반환
* OAuth2 로그인 또는 회원가입 <br> [state]는 nullable한 입력 값이다.<br> 1. OAuth2Client를 이용해 해당 provider로부터
* 유저정보를 가져옴 2. authToken으로 유저를 찾거나 없으면 회원가입 3. 토큰 발급, 유저정보 반환
*/
public Pair<JwtToken, UserModel> oAuth2LoginOrSignup(OAuth2Provider provider, @NonNull String code, @Nullable String state) {
public Pair<JwtToken, UserModel> oAuth2LoginOrSignup(OAuth2Provider provider,
@NonNull String code, @Nullable String state) {
OAuth2Client oAuth2Client = oAuth2Clients.stream()
.filter(client -> client.canHandle(provider))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("지원하지 않는 OAuth2Provider 입니다."));
.filter(client -> client.canHandle(provider))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("지원하지 않는 OAuth2Provider 입니다."));

// OAuth2Client를 이용해 해당 provider로부터 유저정보를 가져옴
OAuthUserInfoModel oAuthUserInfoModel = oAuth2Client.getAuthToken(code, state);

// authToken으로 유저를 찾아서 없으면 [OAuthUserInfoModel]를 통해서 회원가입 진행
User user = userReader
.findByAuthToken(oAuthUserInfoModel.authToken())
.orElseGet(() -> signup(oAuthUserInfoModel, provider));
.findByAuthToken(oAuthUserInfoModel.authToken())
.orElseGet(() -> signup(oAuthUserInfoModel, provider));

// 토큰 발급, 유저정보 반환
JwtToken jwtToken = createToken(user);
Expand All @@ -53,7 +52,7 @@ public Pair<JwtToken, UserModel> oAuth2LoginOrSignup(OAuth2Provider provider, @N

private User signup(OAuthUserInfoModel oAuthUserInfoModel, OAuth2Provider provider) {
UserCommand.CreateOAuth2 command = oAuthUserInfoModel.toCreateCommand(provider);
User user = User.create(command);
User user = User.create(command);
return userStore.store(user);
}

Expand All @@ -63,11 +62,11 @@ private JwtToken createToken(User user) {
}

@Transactional
public Pair<JwtToken, UserModel> signup(UserCommand.Create command){
if(userReader.existsByEmail(command.getEmail())){
public Pair<JwtToken, UserModel> signup(UserCommand.Create command) {
if (userReader.existsByEmail(command.getEmail())) {
throw new IllegalArgumentException("이미 존재하는 이메일입니다.");
}

command = command.copyEncodedPassword(passwordEncoder.encode(command.getPassword()));
User user = User.create(command);
userStore.store(user);
JwtToken jwtToken = createToken(user);
Expand All @@ -76,21 +75,21 @@ public Pair<JwtToken, UserModel> signup(UserCommand.Create command){
}

@Transactional
public void createManager(UserCommand.Create command){
if(userReader.existsByEmail(command.getEmail())){
public void createManager(UserCommand.Create command) {
if (userReader.existsByEmail(command.getEmail())) {
throw new IllegalArgumentException("이미 존재하는 이메일입니다.");
}

command = command.copyEncodedPassword(passwordEncoder.encode(command.getPassword()));
User user = User.createManager(command);
userStore.store(user);
}

@Transactional(readOnly = true)
public Pair<JwtToken, UserModel> login(String email, String password) {
User user = userReader.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 이메일입니다."));
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 이메일입니다."));

if(!passwordEncoder.matches(password, user.getPassword())){
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new IllegalArgumentException("비밀번호가 일치하지 않습니다.");
}

Expand All @@ -100,7 +99,7 @@ public Pair<JwtToken, UserModel> login(String email, String password) {
}

public String reissueToken(String rawToken) {
if(!jwtUtils.validateToken(rawToken)){
if (!jwtUtils.validateToken(rawToken)) {
throw new IllegalArgumentException("RefreshToken이 유효하지 않습니다.");
}
JwtToken.ValidToken token = JwtToken.ValidToken.of(rawToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@AllArgsConstructor
@Table(name = "users")
public class User extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down Expand Up @@ -40,48 +41,54 @@ public class User extends BaseTimeEntity {

public static User create(UserCommand.CreateOAuth2 command) {
return User.builder()
.nickname(command.getNickname())
.email(null)
.password(null)
.role(Role.USER)
.provider(command.getProvider())
.authToken(command.getAuthToken())
.exp(0)
.profileImageUrl(null)
.build();
.nickname(command.getNickname())
.email(null)
.password(null)
.role(Role.USER)
.provider(command.getProvider())
.authToken(command.getAuthToken())
.exp(0)
.profileImageUrl(null)
.build();
}

public static User create(UserCommand.Create command){
public static User create(UserCommand.Create command) {
if (!command.isValid()) {
throw new IllegalStateException("인코딩에 실패하였습니다.");
}
return User.builder()
.nickname(command.getNickname())
.email(command.getEmail())
.password(command.getPassword())
.role(Role.USER)
.provider(null)
.authToken(null)
.exp(0)
.profileImageUrl(null)
.build();
.nickname(command.getNickname())
.email(command.getEmail())
.password(command.getPassword())
.role(Role.USER)
.provider(null)
.authToken(null)
.exp(0)
.profileImageUrl(null)
.build();
}

public static User createManager(UserCommand.Create command){
public static User createManager(UserCommand.Create command) {
if (!command.isValid()) {
throw new IllegalStateException("인코딩에 실패하였습니다.");
}
return User.builder()
.nickname(command.getNickname())
.email(command.getEmail())
.password(command.getPassword())
.role(Role.MANAGER)
.provider(null)
.authToken(null)
.exp(0)
.profileImageUrl(null)
.build();
.nickname(command.getNickname())
.email(command.getEmail())
.password(command.getPassword())
.role(Role.MANAGER)
.provider(null)
.authToken(null)
.exp(0)
.profileImageUrl(null)
.build();
}

public void update(UserCommand.Update userUpdate) {
this.nickname = userUpdate.getNickname();
}

public void addExp(Integer exp){
public void addExp(Integer exp) {
this.exp += exp;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,50 @@
import org.haedal.zzansuni.domain.auth.OAuth2Provider;

public class UserCommand {

@Getter
public static class Create extends SelfValidating<UserCommand.Create> {

@Email(message = "이메일 형식은 유효하여야 합니다.")
private final String email;
@NotBlank(message = "password는 필수입니다.")
private String password;
private final String password;
@NotBlank(message = "닉네임은 필수입니다.")
private final String nickname;

private final String encodedPassword;

@Builder
public Create(String email, String password, String nickname) {
this.email = email;
this.password = password;
this.nickname = nickname;
this.encodedPassword = null;

this.validateSelf();
}

public UserCommand.Create changePassword(String encodedPassword){
this.password = encodedPassword;
return this;
private Create(String email, String password, String nickname, String encodedPassword) {
this.email = email;
this.password = password;
this.nickname = nickname;
this.encodedPassword = encodedPassword;
}

public UserCommand.Create copyEncodedPassword(String encodedPassword) {
return new Create(email, null, nickname, encodedPassword);
}

public boolean isValid() {
return password == null && encodedPassword != null;
}


}

@Getter
public static class CreateOAuth2 extends SelfValidating<UserCommand.CreateOAuth2> {

private final String authToken;
private final String nickname;
@NotNull(message = "OAuth2Provider는 필수입니다.")
Expand All @@ -44,7 +63,7 @@ public CreateOAuth2(String authToken, String nickname, OAuth2Provider provider)
this.authToken = authToken;
this.nickname = nickname;
this.provider = provider;
if(authToken.isBlank() || nickname.isBlank()){
if (authToken.isBlank() || nickname.isBlank()) {
throw new RuntimeException("authToken, nickname은 필수입니다.");
}
this.validateSelf();
Expand All @@ -53,6 +72,7 @@ public CreateOAuth2(String authToken, String nickname, OAuth2Provider provider)

@Getter
public static class Update extends SelfValidating<UserCommand.Update> {

@NotBlank(message = "닉네임은 필수입니다.")
private final String nickname;

Expand Down

0 comments on commit bdac9c2

Please sign in to comment.