이전 로직에서는 api가 결국은 signin 페이지에 엔티티의 userid, userpw 그리고 상황 별 페이지 반환 값을 제공했다.
그러나 프론트 놈들이 message, success, property를 parameter로 받길 원해서 난관에 부딪혔다.
먼저 코드를 짤 때, 서로서로 원하고 주고받는 것이 무엇인지 생각하고 짜는 것이 중요해 보인다.
프론트에서 요청한 값은 다음과 같다.
userId와 userPw를 값으로 줬을 때, 해당하는 아이디와 비밀번호를 DB의 값과 비교하고,
여러 상황에 맞추어 "message" : "상황 별 설명", "success" : "성공 여부", "property" : "페이지 반환 값"
그렇다면, 상황은 4가지이다.
1) 아이디 / 비밀번호 일치
2) 아이디는 일치하나, 비밀번호가 불일치
3) 아이디 불일치
4) 자체적인 오류 (비교 불가)
각 상황마다 반환할 값을 부여해 보자.
1) 아이디 / 비밀번호 일치 - "message" : "로그인 성공", "success" : true, "property" : 200
2) 아이디는 일치하나, 비밀번호가 불일치 - "message" : "비밀번호 불일치", "success" : false, "property" : 301
3) 아이디 불일치 - "message" : "존재하지 않는 아이디", "success" : false, "property" : 302
4) 자체적인 오류 (비교 불가) - "message" : "로그인 중 에러 발생", "success" : false, "property" : 303
엔티티부터 수정해 보자.
@AllArgsConstructor
@ToString
@NoArgsConstructor
@Entity
@Getter
public class Signin {
@Transient
Integer property;
@Transient
Boolean success;
@Transient
String message;
@Id
@JsonIgnore
private String userId;
@Column
@JsonIgnore
private String userPw;
public Signin(String userId, String userPw) { //엔티티 객체가 더 생성됨에 따라 생성자 생성
this.userId = userId;
this.userPw = userPw;
}
public void resultC(Signin signin){
this.property = 200;
this.success = true;
this.message = "로그인 성공";
}
public void resultF1(Signin signin){
this.property = 301;
this.success = false;
this.message = "비밀번호 불일치";
}
public void resultF2(Signin signin){
this.property = 302;
this.success = false;
this.message = "존재하지 않는 아이디";
}
public void resultF3(Signin signin){
this.property = 303;
this.success = false;
this.message = "로그인 중 에러 발생";
}
}
- 어노테이션을 추가했다.
@Transient - 엔티티에 추가하나, DB에 추가하지 않을 값
@JsonIgnore - return값으로 반환하고 싶지 않을 때, 본 어노테이션을 추가하여 반환 값에 제외
- Signin이라는 퍼블릭 메소드를 만들었다. DTO파일에서 toEntity()라는 메소드를사용하는데 오류가 발생하였다. 엔티티 객체가 더 생성됨에 따라서 생성자가 따로 생성되는것이 아니라고 판단했고, toEntity()라는 메소드를 위한 생성자를 따로 만들어준 셈이다.
- 보내야 하는 결괏값에 따라 다른 값이 출력되도록 메소드를 만들어 주었다. 앞선 조건에 의한 값이 반환되도록 파라미터들을 최신화해주는 메소드가 되겠다.
다음은 컨트롤러파일을 건드려보자.
@RestController
@Slf4j
public class SigninApiController {
@Autowired
private SigninService signinservice;
@PostMapping("/signin")
public HttpEntity<Signin> signin(@RequestBody SigninForm dto){
Signin signed = signinservice.login(dto);
if(signed.getProperty() == 200) {
return ResponseEntity.status(HttpStatus.OK).body(signed);}
if(signed.getProperty() == 301)
return ResponseEntity.status(301).body(signed);
if(signed.getProperty() == 302)
return ResponseEntity.status(302).body(signed);
else return ResponseEntity.status(303).body(signed);
}
}
간단하다. 이전 코드와 다른 점이라면 null값 유무에 따라 로그인의 여부만 반환했다면, 이번에는 단계적으로 구분 지어 값을 반환하게 된다.
사실상 컨트롤러에서는 주고받는 느낌이 강하여 로직은 service에서 확인하겠다.
마지막, 서비스다.
@Slf4j
@Service
public class SigninService {
@Autowired
private SigninRepository signinRepository;
public Signin login(SigninForm dto) {
Signin user = dto.toEntity();
if(user.getUserId() == null || user.getUserPw() == null){
// 잘못된 입력 303
user.resultF3(user);
return user;
}
log.info("id = {}, pw = {}", user.getUserId(),user.getUserPw());
Optional<Signin> byUserId = signinRepository.findByUserId(user.getUserId());
if (byUserId.isPresent()){
Signin register = byUserId.get();
if (register.getUserPw().equals(user.getUserPw())){ //등록되어 있는 비밀번호 .equals 유저가 입력한 비밀번호 비교
// 비밀번호 일치 200
user.resultC(user);
return user;
}
else {
// 비밀번호 불일치 301
user.resultF1(user);
return user;
}
}
else {
//조회 결과 없음 302
user.resultF2(user);
return user;
}
}
}
로직을 설명하겠다.
1) 잘못된 입력 - 303 입력받은 json데이터의 이름이 잘못되어 userId와 userPw가 반환되지 않는 경우
2) 200 전부 일치!
3) 301 비밀번호 불일치!
4) 302 아이디가 틀렸다!
엔티티에 등록한 메서드를 통해 반환해야 하는 값을 반환할 수 있도록 해준 것이 다다.
비교하는 로직 자체는 변화한 것이 없으며, 반환 값을 추가하는 메소드를 작성하여 덧씌운 것이 다다.
어렵게 생각하지 말자.
끝으로 내가 했던 실수들을 적어보자.
- return 하는 값에 여러 변수를 넣으려고 한 것 -> 리턴되어야 하는 변수 자체가 옵셔널로 바인딩되어있는 것도 확인 안 한 채로!
- signin 메소드에 변수를 넣으려고 한 것
- 잘 모르겠으면 내가 하고자 하는 것을 구교수님께 여쭤보도록 하자.
'BackEnd > Spring boot' 카테고리의 다른 글
| 스프링부트 - 간단한 로그인 #1 (9) | 2021.07.11 |
|---|


