스프링 공부 77

[이론정리] DTO 공부하다가 나머지도 공부하게 되는 과정

DAO DAO(Data Access Object) 는 데이터베이스의 data에 접근하기 위한 객체이며, DataBase에 접근 하기 위한 로직 & 비지니스 로직을 분리하기 위해 사용한다. 현재까지 사용한 DAO는 Entity(데이터베이스에 저장되는 형태) 밖에 없는 것 같다. DTO DTO(Data Transfer Object) 는 계층 간 데이터 교환을 하기 위해 사용하는 객체로, DTO는 로직을 가지지 않는 순수한 데이터 객체이다. 생성자와 getter정도만 쓰는 것 같다. DTO는 DAO가 그대로 외부에 나갈 때, 안전하지 않을 위험이 있기 때문에 사용한다고 이야기를 듣고 사용하다가, 이번에 어떤 용도인지 알게 되었다. 또한, 기능적 로직을 가지지 않게 해야겠다는 생각도 든다. VO VO(Value..

[스프링] 12. Member 엔티티에 대해 생각해보기

기본적인 설정들은 어느정도 만들어두었다. 모든 로직들을 만들고, 이에 대한 테스트 및 정리들을 해볼까 한다. 일단 회원부터 가지고 있어야 할 인스턴스들과, 로직들을 생각해봐야 한다. 회원 엔티티 인스턴스들 아이디(username) 닉네임(nickname) 이메일 비밀번호 역할 가입일자(BaseTimeEntity에 추가된다) 최근 수정일자(BaseTimeEntity에 추가된다. 수정일자가 1달이 넘으면 비밀번호 변경 요청을 보낸다) 기능 회원가입 로그인 닉네임 수정 비밀번호 수정 이메일 수정 비밀번호 변경 요청여부 확인 이러한 기능들을, 데이터베이스를 사용하지 않고 Member라는 도메인에서 사용할 수 있는 로직들로 어떤 부분들이 필요할지 생각해보아야 한다. 최소단위의 기능 회원정보를 가져오면 Member..

[스프링] 11. BaseEntity를 만들어보자.

모든 엔티티에 공통적으로 쓰이는 부분들을 만들어두어야겠다. 일단, 기본적으로 데이터베이스에 들어가기 위해서는 모든 테이블에 id라는 속성이 존재한다. 또한, 생성일자, 수정일자를 등록해서 사용하려고 한다. 생성, 수정일자의 경우에는 사용자 : 비밀번호 최종 수정일자를 확인해, 수정일자를 기준으로 일정 기간이 지나면 비밀번호 재설정을 요청하는 알림을 추가한다. 게시물 : 게시물 작성일자를 추가하고, 수정되었을 경우, 수정됨을 알릴 수 있다. 댓글 : 게시물과 마찬가지로 작성일자, 수정일자를 추가한다. 메시지 : 카톡과 마찬가지로, 보내진 시간등을 설정해둘 수 있다. 이렇게 다양하게 쓰이기 때문에, BaseEntity로 설정해, 모든 엔티티에서 추가적으로 id, createdTime, updatedTime을..

[스프링] 10. JWT를 구현하기. 찐막: 필터만들기와 SecurityConfiguration에 JWT 추가하기

일단, 필터를 만들어서 우리가 해야할 일을 알아야 한다. 토큰을 받아왔을 때, "Authorization"으로 되어있는 헤더를 가져온다. 이 헤더에 대한 인증 방식이 우리의 토큰과 같을 경우, 토큰 부분을 떼고 나머지를 가져온다. 이 부분이 사용 가능한 토큰인 경우, 사용자의 인증정보를 Authentication에 담아주면 된다. 이러한 동작을 필터에서 만들어주면 된다. 일단, 토큰을 받아왔을 때 필요한 부분만을 가져와주는 동작을 만들었다. private String resolveToken(HttpServletRequest request) { String bearerToken = request.getHeader(AUTHORIZATION_HEADER); if (StringUtils.hasText(beare..

[스프링] 9. JWT를 구현하기. 2단계: 인증의 예외를 가져와보자.

Token Provider에서 토큰의 서명, 토큰 자체의 문제에 대한 예외를 처리하거나, 토큰의 지원여부와 만료여부에 대한 예외도 처리했다. 그런데도 처리해야할게 남았다. 뭘까...? 생각해보면,우리가 보낸 예외처리에 대해 어떻게 반응해야 할지 처리를 안했다. 이전에 만들었던 validateToken부분에서는 모든 예외를 받아와 이를 로그로 출력시키는 과정을 만들어두었다. 그렇다면, 사용자에게 해당 예외에 대해 어떻게 처리할지 알아야 한다. (AuthenticationEntryPoint) 또한, 이 때는 토큰에 문제가 있을 경우에만 처리가 되었으며, 토큰에 문제가 없는데 토큰에 있는 사용자의 권한상 해당 요청을 할 수 없을 경우 이를 처리해주어야 한다. (예를 들면, 사용자가 관리자 페이지를 가면 곤란해..

[스프링] 8. JWT를 구현하기. 1단계: 일단 JWT를 위한 토큰을 만들자. (2)

이전에 정리해두었던 TokenProvider의 기능들을 정리해보려고 한다. 일단 생성자! public TokenProvider(@Value("${jwt.secret}") String secretKey) { byte[] keyBytes = Decoders.BASE64.decode(secretKey); this.key = Keys.hmacShaKeyFor(keyBytes); } @Value에서 jwt.secret는 application.yml에서 가져오는 것이다. jwt: secret: 이런식으로 되어있을 때, secret: 뒤에 사용할 키를 적으면 된다. 이전 페이지에서 정리를 간단히 했던 것 같은데, 그게 전부라 설명은 스킵! public TokenDto generateTokenDto(Authentica..

[스프링] 7. JWT를 구현하기. 1단계: 일단 JWT를 위한 토큰을 만들자. (1)

기본적인 스웨거와 CORS에 대한 처리를 완료했다. 이제 JWT(Json Web Token)를 만들어주고, 멤버 로직을 짜기 시작해야 한다. JWT를 정리한 내 순서는 TokenProvider, TokenDto 예외처리들 JwtFilter Filter를 SecurityConfig에 넣기 의 과정으로 정리할 것이며, 일단 토큰에 대해서 코드를 정리해봐야 겠다. 그럴려면, 일단 토큰이 있어야지! @Getter @NoArgsConstructor @AllArgsConstructor @Builder public class TokenDto { private String grantType; private String accessToken; private String refreshToken; private Date a..

[이론정리] Json Web Token

진짜 어디든 있는 JWT, Json Web Token에 대해서 간단하게 정리를 해보려고 한다. 모든 내용은 JWT 공홈 설명에서 발췌했다. JWT란 무엇인가? Json Web Token, 이하 JWT란 일종의 전자 서명으로 사용자가 직접 가지고 있는 컴팩트한 토큰이다. 전자서명처럼 어떤 사용자인지 JWT를 통해 알 수 있다. HMAC알고리즘을 사용하며, RSA나 ECDSA같은 공개키와 개인키를 이용한 암호화가 이루어져 있다. JWT를 통해 그 속에 담긴 안에 있는 claim(주장, 혹은 내용)의 무결성을 검증할 수 있다. 비대칭키(공개키와 개인키가 서로 다르지만 이를 토대로 암호화, 복호화가 되는) 암호화를 통해 토큰이 만들어졌을 때, 해당 사용자만 토큰을 토대로 인증을 할 수 있게 한다. JWT를 언제..

[스프링] 6. SecurityUtil 예외처리를 커스텀 해보자(부제: 2단계, 리스폰스를 이용해 예외처리하기)

이렇게 예외를 따로 만들었으며, 이를 통해 예외처리를 조금 더 직관적이게 만들 수 있었다. 일단, 이전에 만들었던 것을 어떻게 이용할 것인가? Exception이라는 것은 결국, Response에서 요청에 대해 실패했음을 알려주어야 한다. 결국, Response.failure를 반환하게 되는 것이다. 이를 어떻게 활용하는 것일까? @RestControllerAdvice public class ExceptionAdvice { @ExceptionHandler(NeedToLoginException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public Response needToLoginException(){ return Response.failure(403, "인증이 되..

[스프링] 5. SecurityUtil 예외처리를 커스텀 해보자(부제: 1단계, Response만들어주기)

public static Long getCurrentMemberId(){ Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if(authentication == null) throw new NeedToLoginException(); if(authentication.getName() == null) throw new NotRightAuthenticationException(); return Long.parseLong(authentication.getName()); } 이전의 SecurityUtil에서 이렇게 만들어, 각 에러 상황에 대해 다른 결과로 예외를 만들기 위해 코드를 조금 다듬었다. 일단 우..