Coding History/project

로그인 기능 구현

BlackBirdIT 2024. 9. 3. 09:23

우선 무엇부터해야될까 생각하던 찰나에 파일을 업로드 할 수 있으니 로그인 기능을 구현해야겠단 생각이 들었다.

그래서 기존에 article 을 만들 때 쓰던 것들을 긁어오는 중이고, 다 긁어오고 오류 없이 할 수 있게 되면 google과 spotify API를 적용시켜 로그인까지 해보려고 한다.

splice를 참고하고 있기 때문에 그 방식을 따라갈까 싶은데 이메일 자체를 로그인 아이디로 만들고 유저 아이디와 유저 네임, 이름을 구별하는 방식을 그대로 따라볼까 생각중이긴하다.

위의 방식을 따르고 싶기 때문에 조금 가공해서 로그인 백엔드를 구성했다.

일단 테이블은,

CREATE TABLE `users` (
                         `id` int(10) NOT NULL AUTO_INCREMENT,
                         `regDate` DATETIME NOT NULL,
                         `updateDate` DATETIME NULL DEFAULT NULL COMMENT '계정 정보 마지막 업데이트 일시',
                         `loginId` varchar(50) NOT NULL COMMENT '자동 생성된 로그인 ID, user-123456 형식',
                         `loginPw` varchar(100) NOT NULL,
                         `u_name` char(20) NOT NULL,
                         `nickname` char(20) NOT NULL,
                         `email` varchar(50) NOT NULL UNIQUE COMMENT '로그인에 사용될 이메일 주소',
                         `delStatus` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '탈퇴 여부 (0=탈퇴 전, 1=탈퇴 후)',
                         `delDate` DATETIME NULL COMMENT '탈퇴 날짜',
                         `sellLevel` SMALLINT(2) NOT NULL DEFAULT 3 COMMENT '판매권한 (없음=3, 있음=5)',
                         `authLevel` SMALLINT(2) NOT NULL DEFAULT 3 COMMENT '권한 레벨 (없음=3, 있음 = 7)',
                         `spotifyLoginId` VARCHAR(100) NULL DEFAULT NULL COMMENT 'Spotify 소셜 로그인 ID',
                         `googleLoginId` VARCHAR(100) NULL DEFAULT NULL COMMENT 'Google 소셜 로그인 ID',
                         PRIMARY KEY (`id`)
);

이렇게,

Controller와 service는 일단 긁어와서 내가 원하는 기능을 가공만했기 때문에 다른 기능들도 막 섞여 있다.
일단은 가입먼저 해둬서 관련된 것만 뽑아오면,

    @RequestMapping("/usr/member/join")
    public String showJoin() {
        return "/usr/member/join";
    }

    @RequestMapping("/usr/member/doJoin")
    @ResponseBody
    public String doJoin(HttpServletRequest req, String loginPw,
                         String name, String nickname, String email) {
        rq = (Rq) req.getAttribute("rq");

        if (Ut.isEmptyOrNull(email))
            return Ut.jsHistoryBack("F-6", Ut.f("이메일을 입력해주세요."));

        if (Ut.isEmptyOrNull(loginPw))
            return Ut.jsHistoryBack("F-2", Ut.f("비밀번호를 입력해주세요."));

        if (Ut.isEmptyOrNull(name))
            return Ut.jsHistoryBack("F-3", Ut.f("이름을 입력해주세요."));

        if (Ut.isEmptyOrNull(nickname))
            return Ut.jsHistoryBack("F-4", Ut.f("닉네임을 입력해주세요."));

        // 이메일 중복 체크
        Member existingMember = memberService.getMemberByEmail(email);
        if (existingMember != null) {
            return Ut.jsHistoryBack("F-7", Ut.f("해당 이메일은 이미 사용 중입니다."));
        }

        // 자동 생성된 loginId (user-랜덤UUID 형식)
        String loginId = "user-" + UUID.randomUUID().toString().substring(0, 8);

        ResultData doJoinRd = memberService.doJoin(loginId, loginPw, name, nickname, email);

        if (doJoinRd.isFail()) {
            return Ut.jsHistoryBack(doJoinRd.getResultCode(), doJoinRd.getMsg());
        }

//        Member member = memberService.getMemberById((int) doJoinRd.getData1());

        return Ut.jsReplace(doJoinRd.getResultCode(), doJoinRd.getMsg(), "/usr/member/login");
    }
    // 이메일 중복 체크.
    public Member getMemberByEmail(String email) {
        return memberRepository.findByEmail(email);
    }
    // 회원가입.
    public ResultData doJoin(String loginId, String loginPw, String name, String nickname, String email) {

        // 새로운 회원 생성
        Member newMember = new Member();
        newMember.setLoginId(loginId);
        newMember.setLoginPw(loginPw);
        newMember.setUName(name);
        newMember.setNickname(nickname);
        newMember.setEmail(email);

        // 회원 저장
        memberRepository.doJoin(newMember);

        return ResultData.from("S-1", "회원가입이 완료되었습니다.", "생성된 회원 id", newMember.getId());
    }

이렇게 해뒀다.

그래서 일단 회원가입 JSP를 구현을 하면 되는데 그 전에 figma에서 해둔거를 한번 추출해보자...

일단 다 추출해서 resouce에 css랑 이미지파일, svg다 넣고 화면을 봤는데 못불러오네?

jsp에서 경로가 딱히 잘못된건 아닌 것 같은데 왜 못불러오지.

파일을 직접 브라우저에서 열어보는 방식으로 해결했다. 지금 파일 하나를 예로 들어서 보면

<img
src="/resources/static/external/vector7364-6soc.svg"
alt="Vector7364"
class="splicecombyhtmltodesign-fre-eversion3008202485712gmt-vector10"/>

이렇게 되어있는데 /resources/static이게 문제였다. 왜 문제인지는 정확하게는 모르겠는데 파일을 찾는 기본 설정이 저게 포함되어있는 것 같다. 그래서 파일로 접근하려고 /resources/static/external/vector 어쩌구 하면
/resources/static/resources/static/external/vector어쩌구로 경로를 찾아서 문제가 됐던 것 같다.
그래서

<img
src="/external/vector7364-6soc.svg"
alt="Vector7364"
class="splicecombyhtmltodesign-fre-eversion3008202485712gmt-vector10"/>

앞을 지워주니까 잘 불러왔다.

그래서 지금은 이런 모습이고 우리는 일단 Sign Up부터 처리해야되니까 여기에 집중하자. 저걸 a태그 처리해서 join으로 경로를 지정해줬다. join.jsp도 만들어줬고.

Join기능에서 애를 좀 많이 먹었다.

Export해서 가져온 HTML이 너무 길어서 어디에 뭐가 있는지 찾는데만 한참이 걸렸고 이후에 Form 태그로 POST하는 과정에서 계속 null이 전송되는 문제와 js로 비밀번호 일치 여부를 만드는데도 id를 추가해놓고 뭐라고 했는지 까먹는다거나 멍청한 실수를 계속 했다..

어찌됐던 일단 다 해결은 해서 Join기능을 완성을 시켰다.

트러블슈팅

NULL을 전송하던 이유. input의 name이 일치하지 않아서 생겼던 문제.
- input Name을 정확하게 파악하고 코드를 씀.(JS도 같은 문제를 겪었음..)
이유2 -> 테이블 칼럼 이름과 필드 변수 이름이 일치하지 않았던 문제
- 변수를 매핑할 수 있게끔 해결함.
id 칼럼에 id INT AUTO_INCREMENT; 선언 안해두고 왜 NULL인지 파악한참함.
- DB 까보고 파악후 수정.

진짜 이렇게 보니까 멍청한 것 같다..

암튼 다음으로 로그인까지 구현해보자.

로그인은 이상한데서 좀 애를 먹었는데, 기존에 했던 게시판 코드를 긁어와서 rq와 인터셉터, 그리고 인터셉터에 필요한 MyWebMVCConfiger까지 싹 긁어오는 과정에서 좀 문제가 있었는지 로그인을 한적이 없는데 계속 로그아웃부터 하라는 문제에 좀 시달렸다. (여담으로 그냥 url에 로그아웃 명령어 실행시키고 다시하면 됐을거다. 아마 테스트하는 과정에서 이미 나도 모르는 사이에 로그인을 성공했던 것으로 추정한다. 해결도 그렇게 했고) 하지만 내 뇌는 이미 이게 왜 문제인가에 시달려서 거의 한시간동안 저렇게 하겠다는 생각을 못하고 헤메다가 그냥 저렇게 하니까 해결됐다. 이게 참.. 이래서 한번씩 바람 쐬고 와야된다는 것 같다.

그래도 로그인까지 다 성공했다. 이제 다음으로는 API를 사용한 로그인 구현을 해보도록 하겠다.