[UMC 10주차] JWT 적용 실습! - 로그인

유보라·2022년 5월 27일
0

UMC 2기

목록 보기
13/14

안녕하세요 보라입니다😀 벌써 UMC 강의의 마지막 주차가 되었네요!

바로 시작하겠습니다!

  1. 실습 과정
  2. 트러블 슈팅
  3. 강의 후기

1. 실습 과정

jwt 로그인 API

코드 작성

이번에는 jwt를 이용하여 로그인 API를 만들어보겠다!

먼저 PostLoginReqPostLoginRes모델을 만들어주자.

  • model
//PostLoginReq
@Getter
@Setter
@AllArgsConstructor
public class PostLoginReq {
    private String email;
    private String pwd;

}


//PostLoginRes
@Getter
@Setter
@AllArgsConstructor
public class PostLoginRes {
    private int userIdx;
    private String jwt;

}
  • UserController
//UserController
	@ResponseBody
    @PostMapping("/login")
    public BaseResponse<PostLoginRes> logIn(@RequestBody PostLoginReq postLoginReq) {
        try{
            //email 입력이 되었는지 확인
            if(postLoginReq.getEmail() == null) {
                return new BaseResponse<>(POST_USERS_EMPTY_EMAIL);
            }
            //pwd 입력이 되었는지 확인
            if(postLoginReq.getPwd() == null) {
                return new BaseResponse<>(POST_USERS_EMPTY_PASSWORD);
            }
            //email 정규식 검증
            if(!isRegexEmail(postLoginReq.getEmail())) {
                return new BaseResponse<>(POST_USERS_INVALID_EMAIL);
            }

            PostLoginRes postLoginRes = userService.logIn(postLoginReq);

            return new BaseResponse<>(postLoginRes);

        } catch(BaseException exception){
            return new BaseResponse<>((exception.getStatus()));
        }
    }
  • UserDAO
//UserDAO
	public User getPwd(PostLoginReq postLoginReq) {
        String getPwdQuery = "SELECT userIdx, name, nickName, email, pwd from User where email = ?";
        String getPwdParams = postLoginReq.getEmail();

        return this.jdbcTemplate.queryForObject(getPwdQuery,
                (rs,rowNum)-> new User (
                        rs.getInt("userIdx"),
                        rs.getString("name"),
                        rs.getString("nickName"),
                        rs.getString("email"),
                        rs.getString("pwd")
                ),
                getPwdParams
        );
    }
  • UserService
//UserService
    public PostLoginRes logIn(PostLoginReq postLoginReq) throws BaseException {
        User user = userDao.getPwd(postLoginReq);
        String encryptPwd;

        try{
            //비밀번호 암호화
            encryptPwd = new SHA256().encrypt(postLoginReq.getPwd());


        } catch(Exception exception){
            throw new BaseException(PASSWORD_ENCRYPTION_ERROR);
        }

        //암호화된 비밀번호와 비교
        if(user.getPwd().equals(encryptPwd)) {
            int userIdx = user.getUserIdx();
            String jwt = jwtService.createJwt(userIdx);
            return new PostLoginRes(userIdx, jwt);
        }
        else {
            throw new BaseException(FAILED_TO_LOGIN);
        }
    }
  • jwtService
    jwtService는 이 강의 파일을 내려 받았을 때 이미 구현이 되어있던 코드인데, 아래 코드를 보면 JWT_SECRET_KEY라는 것이 있다. 현재는 config.secret 경로에 임의로 암호화 KEY가 작성되어 있고 이 KEY는 절대 노출되면 안된다! 깃허브에 올릴 때도 조심하도록 하자~
 public String createJwt(int userIdx){
        Date now = new Date();
        return Jwts.builder()
                .setHeaderParam("type","jwt")
                .claim("userIdx",userIdx)
                .setIssuedAt(now)
                .setExpiration(new Date(System.currentTimeMillis()+1*(1000*60*60*24*365)))
                .signWith(SignatureAlgorithm.HS256, Secret.JWT_SECRET_KEY)
                .compact();
    }

POSTMAN 테스트!

POSTMAN에서 jwt 로그인 테스트를 해보기 전에, 비밀번호가 암호화 된 계정이 하나 있어야 하므로 회원가입을 진행해주었다.

그리고 테스트를 해보았다.

성공!

JWT 헤더

코드 작성

  • PostController
    기존에 작성되어있던 PostController에 코드를 추가해주었다.
//PostController
	@ResponseBody
    @PostMapping("")
    public BaseResponse<PostPostsRes> createPost(@RequestBody PostPostsReq postPostsReq) {
        try{
        	//*****여기부터 추가된 코드*****
            //jwt
            int userIdxByJwt = jwtService.getUserIdx();
            //맞는지 검증
            if(postPostsReq.getUserIdx() != userIdxByJwt) {
                return new BaseResponse<>(BaseResponseStatus.INVALID_USER_JWT);
            }
			//*****여기까지 추가된 코드*****
			
            //게시물 본문의 길이가 너무 길 때
            if(postPostsReq.getContent().length() > 450) {
                return new BaseResponse<>(BaseResponseStatus.POST_POSTS_INVALID_CONTENTS);
            }
            //사진이 선택되지 않았을 때
            if(postPostsReq.getPostImgUrls().size() < 1) {
                return new BaseResponse<>(BaseResponseStatus.POST_POSTS_EMPTY_IMGURL);
            }

            PostPostsRes postPostsRes = postService.createPost(postPostsReq.getUserIdx(), postPostsReq);
            return new BaseResponse<>(postPostsRes);

        } catch(BaseException exception){
            return new BaseResponse<>((exception.getStatus()));
        }
    }

POSTMAN 테스트

저번 주차에 만들었던 게시물 생성 API 코드를 다시 테스트해보자!

위와 같이 jwt를 입력하라고 뜬다.

위처럼 헤더에 jwt 키를 추가해주었다.

그러면 Body result에서는 null이라고 뜨긴 하는데, db로 들어가보면 요청이 잘 수행되었다!

아래는 Post 테이블이고, 가장 아래에 방금 만든 게시물 데이터가 생겼다 ㅎㅅㅎ

방금 테스트를 할 때 jwt 값을 살짝 바꿔주었을 때는 유효하지 않는 jwt라고 뜬다.

구현 성공!

2. 트러블 슈팅

문제 원인

jwt 로그인 테스트를 위해 회원가입을 하려고 했는데 에러가 발생했다.

해결 방안

알고 보니, 내 DB에서는 column을 pwd라고 만들어주었는데 여기저기서 password와 pwd를 번갈아 사용하다보니 헷갈린 거였다! password를 pwd라고 고쳐주었다.

그랬더니...

문제 원인

아래 코드에서 에러가 난 것 같았다.

해결 방안

알고보니 pwd가 그대로 db에 들어가는 것이 아니라, 암호화 처리가 되어서 엄청 길게 들어가기 때문에 내 db에 설정되어있는 pwd varchar(20) 가지고는 택도 없었던 것이었다. pwd의 타입을 TEXT로 수정해주니 해결되었다!

3. 강의 후기

한 학기 동안 많은 걸 하려고 욕심을 냈다 보니, 조금 버거운 적도 있었던 것 같다. 학교 강의들(3학년이다보니 전공도 많이 듣고 과제도 많았는데 그나마 듣는 교양도 수학이라서...), 학생회 집부 활동, UMC 강의 그리고 주짓수까지.. 솔직히 주짓수에 가장 열심히 임한 것 같다 ㅋㅋㅋㅋ 공부도 중간고사 때까지는 열심히 했는데 그 이후로 의욕을 잃은 듯하다...^^

그리고 Spring boot를 처음 다루어 보는데 좋은 강의를 만나서 정말 의미있는 경험이었고, 이 지식들을 바탕으로 더 쉽게 웹 개발을 할 수 있을 것 같다. 내 자신에게 솔직해지자면 최선을 다하지 못한 주차도 있었고, 에러 해결도 못해서 계속 다음 주로 다다음 주로 미루기도 했지만, 모든 경험들이 다 다음 프로젝트 때 거름이 될 것 같다!!

profile
인하대학교 컴퓨터공학과 학생입니다😀

0개의 댓글