Spring 게시판 12- 로그인API

춤인형의 개발일지·2025년 1월 17일

Spring실습

목록 보기
13/40

로그인 API

  • 로그인은 post일까 Get일까?
    로그인은 사용자가 입력했을 때, 보내는거니까 post!
  • loginRequest에는 뭐가 들어갈까?
    요청 줄 값은 로그인 정보인 아이디, 비밀번호를 준다.

1) LoginRequest

public record LoginRequest(
        String userId,
        String password
) {
}

2) controller

@PostMapping("/login")
    public void login(@RequestBody LoginRequest loginRequest){
        userService.login(loginRequest);
    }

3) service

  • a) loginRequest안에는 로그인 아이디(UserId)와 비밀번호(password)밖에 없으니까 요청이 들어온 Request안에 아이디(userId)가 실제 엔티티(데이터)에 들어왔나를 확인해줘야한다.
  • b)userId와 실제 데이터값과 비교한다.

쿼리메서드를 작성해서 아이디(UserId)를 찾는 함수를 작성해준다.

//repository에 작성
UserInfo findByUserId(String userId);
public void login(LoginRequest loginRequest) {
//a)
        UserInfo user = userRepository.findByUserId(loginRequest.userId());
        //b)
        if(!user == null)){ // user자체에 지금 UserId를 찾아왔으니까 '!user.getUserId().equals(loginRequest.userId())'를 할 필요가 없는 것
        }
            throw new NoSuchElementException("아이디, 비밀번호가 틀렸습니다.");
        }
        if (!SecurityUtils.sha256EncryptBase64(loginRequest.password()).equals(user.getPassWord())){
            throw new NoSuchElementException("아이디, 비밀번호가 틀렸습니다.");
        }
    }

SecurityUtils.sha256EncryptBase64 -> 비밀번호 해쉬화
데이터에 들어있는 비밀번호는 한번 해쉬화를 했기 때문에 해쉬화를 하지 않은 request의 데이터들을 그냥 비교하면 당연히! 다르다고 한다. 따라서 요청이 들어온 request를 해쉬화로 바꿔줘야한다.

해쉬화

비밀번호를 그냥 노출하는건 굉장히 위험하기 때문에 알아보기 어렵게 코드화같이 문자를 다르게 바꿔두는 것이다. 대문자로만 바꿔도 해쉬는 완전히 달라진다.

로그인이 잘 동작하는지 테스트를 진행한다.

 @Test
    void 로그인테스트() {
        UserResponse 사용자 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new UserRequest("추민영", "chuchu", "abcABC123!!!", "chu@naver.com"))
                .when()
                .post("/users/infos")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new LoginRequest("chuchu", "abcABC123!!!"))
                .when()
                .post("/login")
                .then().log().all()
                .statusCode(200);
    }

토큰 생성하기

로그인은 내가 그 사용자라는 증표(증거)가 필요하다. 그걸 토큰이라 부른다.
토큰을 만들어서 서버에 전송해줘야 내가 이 사용자라는 것을 알려주게 된다.

1) Response에 token을 하나 내보내준다.

public record LoginResponse(
        String token
) {
}

2) controller에 loginResponse로 output값을 바꿔준다.

//로그인 API
    @PostMapping("/login")
    public LoginResponse login(@RequestBody LoginRequest loginRequest){
        return userService.login(loginRequest);
    }

3) service
Jwtprovider를 하나 만들어주고, 그 곳에서 토큰을 생성해주는 함수를 만들어준다. 그걸 가져오기만 하면된다.

public LoginResponse login(LoginRequest loginRequest) {
        UserInfo user = userRepository.findByUserId(loginRequest.userId());
        if(!user.getUserId().equals(loginRequest.userId())){
            throw new NoSuchElementException("아이디, 비밀번호가 틀렸습니다.");
        }
        if (!SecurityUtils.sha256EncryptBase64(loginRequest.password()).equals(user.getPassWord())){
            throw new NoSuchElementException("아이디, 비밀번호가 틀렸습니다.");
        }
        return new LoginResponse(jwtProvider.createToken(loginRequest.userId()));
    }

토큰 생성 테스트

 @Test
    void 로그인테스트() {
        UserResponse 사용자 = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new UserRequest("추민영", "chuchu", "abcABC123!!!", "chu@naver.com"))
                .when()
                .post("/users/infos")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(UserResponse.class);

        LoginResponse token = RestAssured
                .given().log().all()
                .contentType(ContentType.JSON)
                .body(new LoginRequest("chuchu", "abcABC123!!!"))
                .when()
                .post("/login")
                .then().log().all()
                .statusCode(200)
                .extract()
                .as(LoginResponse.class);


        assertThat(token).isNotNull();
    }

테스트도 잘 통과하는 것을 확인하였다.

🔺쿠키랑 토큰을 쓰면 로그인을 했다는걸 어케 알지요?
-> 쿠키나 토큰은 로그인했다는 증거를 유저가 가지고 있는 것이다. 매번 id, 비밀번호를 주지 않아도 증거만 있으면 된다.

  • 토큰: 정보가 다 있음. 위조된게 아니면 무조건 믿는다.
  • 세션 :key하나밖에 없기에 서버가 관리하고 있는 key를 찾아본다. 그러면 그 사람이 누군지를 파악한다.
    둘의 차이는 이러하며 세션이 한번 더 검사하는 느낌이다.

😐 느낀점

로그인을 구현할 때 가장 중요한 2가지가 있다.
1. 해쉬화되어 있는 상태의 비밀번호를 해쉬화가 안된 비밀번호와 비교하면 안된다.
2. 로그인은 내가 이 계정의 사용자라는 것을 알 수 있는 증표(증거)가 꼭! 필요하다
-> 그것이 바로 토큰! 토큰이 있어야 계정에 들어갈 수 있다.

0개의 댓글