[프로젝트] 웹 TripRecorder - 주말1

_bean_·2023년 6월 11일
0
post-thumbnail

오류 및 문제점

1. UserDetails.getUsername()

  • 문제점: 로그인을 시도할 때 UserVO의 변수가 userId이다.
  • 해결 방안: UserDetails를 구현한 클래스에서 getUsername 시 userId를 반환하도록 한다.
@Override
public String getUsername() {
	return user.getUserId();
}

2. payload 디코딩 시 한글 깨짐

  • 문제점: 정보를 얻기 위해 payload를 디코딩하면 한글이 깨진다.
  • 해결 방안: 한글은 2Byte이기 때문에 byte로 변환 후 디코딩해야 한다.
decodeStr = new String(decoder.decode(jwtstring.replace('.', '@').split("@")[1]), "UTF-8").trim();

3. payload 객체로 전달

  • 문제점: front에서 로그인 정보를 사용하기 위해 JSON 객체로 전달하고자 한다.
  • 해결 방안: json simple 라이브러리를 이용해 디코딩한 문자열을 JSON 객체로 변환한다.
// Controller.java
JSONParser parser = new JSONParser();
JSONObject jsonObj = (JSONObject) parser.parse(decodeStr);

HeaderInfo info = HeaderInfo.builder()
	.userno(jsonObj.get("userno"))
    .uesrid(jsonObj.get("userid"))
	.usernick(jsonObj.get("usernick")).build();

return info;
    
// HeaderInfo.java
public class HeaderInfo {
	private Object userno;
	private Object uesrid;
	private Object usernick;
}

진행상황

1. JWT 로그인/회원가입 예제

  • 참고 자료에 있는 인프런 강의를 따라했다. 역시 설명을 들으며 하는 것이 잘 이해된다.
  • 처음에는 이해가 잘 되지 않아 username, password 변수로 로그인 정보를 담을 LoginRequestDto를 따로 만들었었다. 로그인 인증을 할 때도 쓰이고 토큰을 검증할 때도 쓰여서 해당 형태로 DTO가 존재해야 한다고 생각했는데 이름이 비슷하다 보니 헷갈렸던 것 같다.
  • 회원 속성이 많기 때문에 이제는 로그인에 필요한 정보만 LoginRequestDto로 만들어 로그인 요청 시에만 사용했다.
// LoginRequestDto.java
public class LoginRequestDto {
	private String userId;
	private String userPw;
}
  • 회원가입 시 비밀번호 암호화
user.setUserPw(bCryptPasswordEncoder.encode(user.getUserPw()));
user.setUserRole(Role.ROLE_USER);
userRepository.save(user);

  • 로그인 시 헤더에 토큰 전송
response.addHeader(JwtProperties.HEADER_STRING, JwtProperties.TOKEN_PREFIX + jwtToken);

  • 권한에 따른 접근 제한
http.antMatchers("/user/**")
	.access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
    .antMatchers("/admin/**")
    .hasRole("ADMIN")
    .anyRequest()
    .permitAll();

2. payload 디코딩

String jwtstring = request.getHeader("Authorization");
Base64.Decoder decoder = Base64.getUrlDecoder();
String decodeStr = new String(decoder.decode(jwtstring.replace('.', '@').split("@")[1]), "UTF-8").trim();

3. 비밀번호 확인

String user1 = userRepository.findByUserId("user1").getUserPw();
String test = "1234";
		
return bCryptPasswordEncoder.matches(test, user1) ? "같아" : "달라";

4. 실제 프로젝트에 적용

@PostMapping("/join")
public String join(@RequestBody UserVO user) {
	ProfileVO profile = ProfileVO.builder().build();
	user.setProfile(profile);
	user.setUserPw(bCryptPasswordEncoder.encode(user.getUserPw()));
	user.setUserRole(Role.ROLE_USER);
	profile.setUser(user);

	urepo.save(user);
	return "회원가입 성공";
}
  • user
  • profile

5. 각종 유틸 묶음

// 비밀번호 암호화
public static String encodingUserPw(String userPw) {
	BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
	return bCryptPasswordEncoder.encode(userPw);
}

// 비밀번호 확인
public static boolean verifyUserPw(String rawPw, String encodedPw) {
	BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
	return bCryptPasswordEncoder.matches(rawPw, encodedPw);
}

// 복호화된 문자열
public static String getDecodedStr(String str) {
	Base64.Decoder decoder = Base64.getUrlDecoder();
	String decodeStr = null;
	try {
		decodeStr = new String(decoder.decode(str), "UTF-8").trim();
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
	}
		
	return decodeStr;
}

// 문자열을 JSON 객체로 반환
public static JSONObject getJsonObj(String str) {
	JSONParser parser = new JSONParser();
	JSONObject jsonObj = null;
	try {
		jsonObj = (JSONObject) parser.parse(str);
	} catch (ParseException e) {
		e.printStackTrace();
	}
		
	return jsonObj; 
}

// 사용
user.setUserPw(EncodingUtil.encodingUserPw(user.getUserPw()));
JSONObject jsonObj = JsonUtil.getJsonObj(decodeStr);

6. 회원가입 시 아아디 중복 체크

@PostMapping(value = "/join/useridCheck")
public boolean postUseridCheck(@RequestBody UserVO user) {
	UserVO findUser = urepo.findByUserId(user.getUserId());
    return findUser != null;
}

참고 자료

profile
어쩌다 풀스택 :3

0개의 댓글