로그인 기능 구현

서지우·2023년 8월 11일

화면에 뿌려주기

AuthController.java

넣어준다.

    @GetMapping("login")
    public String loginPage(){
        return "login";
    }

잘 나오는 걸 확인했다.


로그인에 필요한 DTO 만들기

ReqLoginDTO.java

package com.example.farmerstroy.domain.auth.dto;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class ReqLoginDTO {

    @Valid
    @NotNull(message = "유저 정보를 입력해주세요")
    private User user;

    @NoArgsConstructor  
    @AllArgsConstructor
    @Builder
    @Getter
    public static class User{

        @NotBlank(message = "아이디를 입력해주세요")
        private String id;
        
        @NotBlank(message = "비밀번호를 입력해주세요")
        private String password;
    }
}

서비스 만들기

AuthServiceApiV1.java

로그인 로직 구현한다.

    // 로그인
    public ResponseEntity<?> login(ReqLoginDTO dto, HttpSession session){
        // 리파지토리에서 아이디가 삭제되지 않은 유저 찾기
        Optional<UserEntity> userEntityOptional = userRepository.findById(dto.getUser().getId());

        // 없으면 존재하지 않음 메시지 리턴
        if (userEntityOptional.isEmpty()) {
            throw new BadRequestException("존재하지 않는 아이디입니다.");
        }

        // 있으면 반환
        UserEntity userEntity = userEntityOptional.get();

        // 비밀번호가 일치하지 않으면 메시지 리턴
        if (!userEntity.getPassword().equals(dto.getUser().getPassword())) {
            throw new BadRequestException("비밀번호가 알치하지 않습니다");
        }

        // 세션에 로그인 유저 정보 저장
        session.setAttribute("dto", LoginUserDTO.of(userEntity));

        // 응답 데이터로 리턴하기
        return new ResponseEntity<>(
            ResponseDTO.builder()
            .code(0)
            .message("로그인에 성공하였습니다.")
            .build()
            ,HttpStatus.OK
        );
    }

세션에 로그인 정보 저장하기 위해 dto만들기

저장하기 위해 만들어준다.

package com.example.farmerstroy.common.dto;

import com.example.farmerstroy.model.user.entity.UserEntity;

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

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@ToString
public class LoginUserDTO {
    
    private User user;

    public static LoginUserDTO of(UserEntity userEntity){
        return LoginUserDTO.builder()
        .user(User.fromEntity(userEntity))
        .build();
    }

    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    @Getter
    @ToString
    public static class User{
        private Long idx;
        // private String nickname;
        private String id;
        private String password;
        // private String email;
        // private String profile;
        // private Integer authority;
        // private List<>

        public static User fromEntity(UserEntity userEntity){
            return User.builder()
            .idx(userEntity.getIdx())
            .id(userEntity.getId())
            .password(userEntity.getPassword())
            .build();
        }
    }
}

그럼 이제 controller로 넘기면 된다!!


데이터 뿌려주기

AuthControllerApiV1.java

    @PostMapping("/login")
    public ResponseEntity<?> login(@Valid @RequestBody ReqLoginDTO dto, HttpSession session){
        return authServiceApiV1.login(dto, session);
    }

스크립트 만들기

loginl.html

<script>
    // 비밀번호 입력창에서 엔터키를 치면 로그인 요청하는 함수
    document.querySelector("#password").addEventListener("keyup", (event) => {
        if (event.keyCode === 13) {
            requestLogin();
        }
    });

    // 로그인 요청하는 함수
    // 로그인 버튼을 누르면 실행
    const requestLogin = () => {
        // 서버와 통신하기 전에 입력값 검증
        if (!validateFields()) {
            return;
        }

        // 로그인 요청
        const dto = {
            user : {
                id : document.getElementById("id").value,
                password : document.getElementById("password").value,
            }
        }
        fetch("/api/v1/auth/login", {
            method : "POST",
            headers : {
                "Content-Type" : "application/json;charset=utf-8"
            },
            body : JSON.stringify(dto)
        })
        .then(reponse => reponse.json())
        .then(result => {
            alert(result.message);
            if (result.code === 0) {
                location.replace("/main");
            }
        })
    };

    // 아이디와 비밀번호 입력창이 비어있는지 검사하는 함수
    const validateFields = () => {
        const idElement = document.querySelector("#id");
        const passwordElement = document.querySelector("#password");

        if (idElement.value === "") {
            alert("아이디를 입력해주세요");
            idElement.focus();
            return false;
        }

        if (passwordElement.value === "") {
            alert("비밀번호를 입력해주세요");
            passwordElement.focus();
            return false;
        }

        return true;
    };

    // 페이지가 로드되면 실행되는 함수
    const setLoginPage = () => {
        // 아이디 입력창에 포커스가 가도록
        const idElement = document.querySelector("#id");
        const passwordElement = document.querySelector("#password");
    }
</script>
<script defer>
    setLoginPage();
</script>

실행해보면 비밀번호가 일치 하지 않으면 아래와 같이 나온다.

아이디가 db에 없으면 아래와 같이 나온다.

맞게 적으면 요렇게 나온다!!

그리고 메인페이지로 이동한다!

profile
미래가 기대되는 풀스택개발자 공부 이야기~~

1개의 댓글

comment-user-thumbnail
2023년 8월 11일

정보 감사합니다.

답글 달기