뉴스피드 프로젝트 6일차
최종 코드
- config 패키지
더보기PasswordConfig
SecurityConfig@Configuration public class PasswordConfig { @Bean public PasswordEncoder passwordEncoder () { return new BCryptPasswordEncoder(); } }
@Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig { private final JwtUtil jwtUtil; private final UserDetailsServiceImpl userDetailsService; private final AuthenticationConfiguration authenticationConfiguration; @Bean public SecurityFilterChain securityFilterChain (HttpSecurity http) throws Exception { http.csrf((csrf) -> csrf.disable()); http.sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS) ); http.authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() .requestMatchers("/users/**").permitAll() .anyRequest().authenticated() ); http.addFilterBefore(jwtAuthorizationFilter(), JwtAuthenticationFilter.class); http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } @Bean public AuthenticationManager authenticationManager (AuthenticationConfiguration configuration) throws Exception { return configuration.getAuthenticationManager(); } @Bean public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception { JwtAuthenticationFilter filter = new JwtAuthenticationFilter(jwtUtil); filter.setAuthenticationManager(authenticationManager(authenticationConfiguration)); return filter; } @Bean public JwtAuthorizationFilter jwtAuthorizationFilter() { return new JwtAuthorizationFilter(jwtUtil, userDetailsService); } }
- controller 패키지
더보기BoardController
CommentController@RequiredArgsConstructor @RestController @RequestMapping("/boards") public class BoardController { private final BoardService boardService; @PostMapping public ResponseEntity<BoardResponseDto> createBoard( @RequestBody BoardRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails ) { Board board = boardService.createBoard(requestDto, userDetails.getUser()); BoardResponseDto boardResponseDto = new BoardResponseDto(board); return new ResponseEntity<>(boardResponseDto, HttpStatus.OK); } @GetMapping public ResponseEntity<List<Board>> getAllBoards() { List<Board> boards = boardService.getAllBoards(); return new ResponseEntity<>(boards, HttpStatus.OK); } @GetMapping("/{boardnum}") public ResponseEntity<BoardResponseDto> getBoardById( @PathVariable Long boardnum ) { Board board = boardService.getBoardById(boardnum); BoardResponseDto boardResponseDto = new BoardResponseDto(board); return new ResponseEntity<>(boardResponseDto, HttpStatus.OK); } @GetMapping("/userboard") public List<BoardResponseDto> getUserAllBoards( @AuthenticationPrincipal UserDetailsImpl userDetails ){ return boardService.getUserAllBoards(userDetails); } @GetMapping("/userboard/{boardnum}") public BoardResponseDto getUserSelectedBoards( @PathVariable Long boardnum, @AuthenticationPrincipal UserDetailsImpl userDetails ) { return boardService.getUserSelectedBoards(boardnum, userDetails); } @PutMapping("/{boardNum}") public ResponseEntity<BoardResponseDto> updateBoard( @PathVariable Long boardNum, @RequestBody BoardUpdateDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) { Board board = boardService.updateBoard(boardNum, requestDto, userDetails.getUser()); BoardResponseDto boardResponseDto = new BoardResponseDto(board); return new ResponseEntity<>(boardResponseDto, HttpStatus.OK); } @DeleteMapping("/{boardNum}") public ResponseEntity<String> deleteBoard( @PathVariable Long boardNum, @AuthenticationPrincipal UserDetailsImpl userDetails ) { boardService.deleteBoard(boardNum, userDetails.getUser()); return ResponseEntity.ok("게시글 삭제 완료"); } }
UserController@RestController @RequiredArgsConstructor @RequestMapping("/boards") public class CommentController { private final CommentService commentService; @GetMapping("/{boardNum}/comment") public List<CommentResponseDto> getCommentsByBoard(@PathVariable("boardNum") Long boardNum){ return commentService.getCommentsByBoard(boardNum); } @PostMapping("/{boardNum}/comment") public ResponseEntity<CommentResponseDto> addComment( @PathVariable("boardNum") Long boardNum, @RequestBody CommentRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails ) { Comment comment = commentService.addComment(boardNum, requestDto, userDetails.getUser()); return new ResponseEntity<>(new CommentResponseDto(comment), HttpStatus.OK); } @PutMapping("/{boardNum}/comment/{commentNum}") public ResponseEntity<CommentResponseDto> updateComment( @PathVariable("boardNum") Long boardNum, @PathVariable("commentNum") Long commentNum, @RequestBody CommentRequestDto commentRequestDto, @AuthenticationPrincipal UserDetailsImpl userDetails ) { Comment comment = commentService.updateComment(boardNum, commentNum, commentRequestDto, userDetails.getUser()); return new ResponseEntity<>(new CommentResponseDto(comment), HttpStatus.OK); } @DeleteMapping("/{boardNum}/comment/{commentNum}") public ResponseEntity<String> deleteComment( @PathVariable("boardNum") Long boardNum, @PathVariable("commentNum") Long commentNum, @AuthenticationPrincipal UserDetailsImpl userDetails ) { commentService.deleteComment(boardNum, commentNum, userDetails.getUser()); return ResponseEntity.ok("댓글 삭제 완료"); } }
@Slf4j @RestController @RequiredArgsConstructor @RequestMapping("/users") public class UserController { private final UserService userService; @PostMapping("/signup") public String signup (@Valid @RequestBody SignupRequestDto requestDto, BindingResult bindingResult) { List<FieldError> fieldErrors = bindingResult.getFieldErrors(); if (!fieldErrors.isEmpty()) { for (FieldError fieldError : bindingResult.getFieldErrors()) { log.error(fieldError.getField() + " 필드 : " + fieldError.getDefaultMessage()); } return "회원가입도중 에러가 발생했습니다."; } userService.signup(requestDto); return "회원가입 성공"; } @PostMapping("/login") public LoginResponseDto login (@RequestBody LoginRequestDto requestDto) { LoginResponseDto responseDto = userService.login(requestDto); return responseDto; } @GetMapping("/info") @ResponseBody public UserDetailsImpl getUserInfo(@AuthenticationPrincipal UserDetailsImpl userDetails) { return userDetails; } // 회원탈퇴 @DeleteMapping("/delete") public ResponseEntity<String> deleteUser(@AuthenticationPrincipal UserDetailsImpl userDetails) { userService.deleteUser(userDetails.getUser()); return ResponseEntity.ok("회원 탈퇴 완료"); } // 프로필 단건조회 @GetMapping public ResponseEntity<ProfileResponseDto> getProfile(@AuthenticationPrincipal UserDetailsImpl userDetails) { ProfileResponseDto response = userService.getProfile(userDetails.getUser().getUserNum()); return new ResponseEntity<>(response, HttpStatus.OK); } // 프로필 수정 @PutMapping public ResponseEntity<ProfileResponseDto> updateProfile(@RequestBody UserUpdateDto request, @AuthenticationPrincipal UserDetailsImpl userDetails) { ProfileResponseDto response = userService.updateProfile(userDetails.getUser().getUserNum(), request); return new ResponseEntity<>(response, HttpStatus.OK); } }
- dto 패키지
더보기RequestDto
BoardRequestDto
BoardUpdateDto@Getter public class BoardRequestDto { String title; String contents; }
@ToString @NoArgsConstructor @AllArgsConstructor @Setter @Getter public class BoardUpdateDto { private String title; private String contents; }
CommentRequestDto
LoginRequestDto@Getter public class CommentRequestDto { private String contents; }
SignupRequestDto@Getter public class LoginRequestDto { private String userId; private String password; }
UserUpdateDto@Getter public class SignupRequestDto { @NotBlank private String userId; @NotBlank private String password; @Pattern(regexp = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$") @NotBlank private String email; @NotBlank private String name; }
@Getter public class UserUpdateDto { @NotBlank private String name; @NotBlank private String userId; @NotBlank private String email; @Pattern(regexp = "^[a-zA-Z0-9]{8,15}$", message = "영대소문자와 숫자만, 8~15길이만 허용") @NotBlank private String password; @Pattern(regexp = "^[a-zA-Z0-9]{8,15}$", message = "영대소문자와 숫자만, 8~15길이만 허용") @NotBlank private String confirmPassword; }
ResponseDto
BoardResponseDto@ToString @Setter @Getter public class BoardResponseDto { private Long boardNum; private String title; private String contents; private String userId; private LocalDateTime createAt; private LocalDateTime modifiedAt; public BoardResponseDto(Board board) { this.boardNum = board.getBoardNum(); this.title = board.getTitle(); this.contents = board.getContents(); this.userId = board.getUser().getUserId(); this.createAt = board.getCreatedAt(); this.modifiedAt = board.getModifiedAt(); } }
CommentResponseDto
@Getter public class CommentResponseDto { private String contents; private String userId; private LocalDateTime createAt; private LocalDateTime modifiedAt; public CommentResponseDto(Comment comment) { this.contents = comment.getContents(); this.userId = comment.getUser().getUserId(); this.createAt = comment.getCreatedAt(); this.modifiedAt = comment.getModifiedAt(); } }
LoginResponseDto
@Getter @Builder public class LoginResponseDto { private String userId; private String password; private String email; private String name; private String token; }
ProfileResponseDto
@Getter public class ProfileResponseDto { private String name; private String userId; private String email; private String password; public ProfileResponseDto(String name, String userId, String email, String password) { this.name = name; this.userId = userId; this.email = email; this.password = password; } }
- entity 패키지
더보기Board
Comment@Getter @NoArgsConstructor @Entity @Table(name = "boards") @AllArgsConstructor public class Board extends Timestamped { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long boardNum; @Column(nullable = false, length = 50) private String title; @Lob private String contents; @ManyToOne @JoinColumn(name = "userNum", nullable = false) private User user; public Board(String title, String content, User user) { this.title = title; this.contents = content; this.user = user; } public void updateBoard(BoardUpdateDto requestDto) { this.title = requestDto.getTitle(); this.contents = requestDto.getContents(); } }
Timestamped@Entity @NoArgsConstructor @AllArgsConstructor @Getter @Table(name = "comments") public class Comment extends Timestamped { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long commentNum; @Lob private String contents; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "userNum", nullable = false) private User user; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "boardNum", nullable = false) private Board board; public Comment(CommentRequestDto requestDto, Board board, User user) { this.contents = requestDto.getContents(); this.board = board; this.user = user; } public void updateComment (CommentRequestDto commentRequestDto) { this.contents = commentRequestDto.getContents(); } }
User@Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public abstract class Timestamped { @CreatedDate @Column(updatable = false) @Temporal(TemporalType.TIMESTAMP) private LocalDateTime createdAt; @LastModifiedDate @Column @Temporal(TemporalType.TIMESTAMP) private LocalDateTime modifiedAt; }
UserRoleEnum@Getter @Entity @Table(name = "users") @NoArgsConstructor public class User extends Timestamped { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long userNum; @Column(nullable = false, unique = true, length = 50) private String userId; @Column(nullable = false) private String password; @Column(nullable = false, unique = true, length = 50) private String email; @Column(nullable = false, length = 50) private String name; @Column(nullable = false) @Enumerated(value = EnumType.STRING) private UserRoleEnum role; public User(String userId, String password, String email, String name, UserRoleEnum role) { this.userId = userId; this.password = password; this.email = email; this.name = name; this.role = role; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof User user)) return false; return Objects.equals(getUserNum(), user.getUserNum()) && Objects.equals(getUserId(), user.getUserId()); } public void updateProfile(String name, String userId, String email, String password) { this.name = name; this.userId = userId; this.email = email; this.password = password; } }
public enum UserRoleEnum { USER(Authority.USER); private final String authority; UserRoleEnum (String authority) { this.authority = authority; } public String getAuthority() { return this.authority; } public static class Authority { public static final String USER = "ROLE_USER"; } }
- jwt 패키지
더보기JwtAuthenticationFilter
@Slf4j(topic = "로그인 및 JWT 생성") public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final JwtUtil jwtUtil; public JwtAuthenticationFilter (JwtUtil jwtUtil) { this.jwtUtil = jwtUtil; // setFilterProcessesUrl("/users/login"); } @Override public Authentication attemptAuthentication ( HttpServletRequest req, HttpServletResponse res ) throws AuthenticationException { log.info("로그인 시도"); try { LoginRequestDto requestDto = new ObjectMapper() .readValue(req.getInputStream(), LoginRequestDto.class); return getAuthenticationManager().authenticate( new UsernamePasswordAuthenticationToken( requestDto.getUserId(), requestDto.getPassword(), null ) ); } catch (IOException e) { log.error(e.getMessage()); throw new RuntimeException(e.getMessage()); } } @Override protected void successfulAuthentication( HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication authResult) throws IOException, ServletException { log.info("로그인 성공 및 JWT 토큰 생성"); String userId = ((UserDetailsImpl) authResult.getPrincipal()).getUsername(); UserRoleEnum role = ((UserDetailsImpl) authResult.getPrincipal()).getUser().getRole(); String token = jwtUtil.createToken(userId, role); res.addHeader(JwtUtil.AUTHORIZATION_HEADER, token); } @Override protected void unsuccessfulAuthentication( HttpServletRequest req, HttpServletResponse res, AuthenticationException failed ) throws IOException, ServletException { log.info("로그인 실패"); res.setStatus(401); } }
JwtAuthorizationFilter
@Slf4j(topic = "JWT 검증 및 인가") @RequiredArgsConstructor public class JwtAuthorizationFilter extends OncePerRequestFilter { private final JwtUtil jwtUtil; private final UserDetailsServiceImpl userDetailsService; @Override protected void doFilterInternal ( HttpServletRequest req, HttpServletResponse res, FilterChain filterChain ) throws ServletException, IOException { String tokenValue = jwtUtil.getJwtFromHeader(req); if (StringUtils.hasText(tokenValue)) { log.info(tokenValue); if (!jwtUtil.validateToken(tokenValue)) { log.error("Token Error"); return; } Claims info = jwtUtil.getUserInfoFromToken(tokenValue); try { setAuthentication(info.getSubject()); } catch (Exception e) { log.error(e.getMessage()); return; } } filterChain.doFilter(req, res); } public void setAuthentication (String userId) { SecurityContext context = SecurityContextHolder.createEmptyContext(); Authentication authentication = createAuthentication(userId); context.setAuthentication(authentication); SecurityContextHolder.setContext(context); } private Authentication createAuthentication (String userId) { UserDetails userDetails = userDetailsService.loadUserByUsername(userId); return new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); } }
- repository 패키지
더보기BoardRepository
CommentRepositorypublic interface BoardRepository extends JpaRepository<Board, Long> { List<Board> findAllByUser(User user); List<Board> findByUser(User user);// (마이페이지) List<Board> findAllByOrderByCreatedAtDesc(); }
UserRepositorypublic interface CommentRepository extends JpaRepository<Comment, Long> { List<Comment> findByBoardBoardNum(Long boardNum); List<Comment> findByBoard(Board board); }
public interface UserRepository extends JpaRepository<User, Long> { Optional<User> findByUserId(String userId); Optional<User > findByEmail(String email); }
- security 패키지
더보기UserDetailsImpl
UserDetailsServiceImpl@RequiredArgsConstructor public class UserDetailsImpl implements UserDetails { private final User user; public User getUser() { return user; } @Override public String getUsername() { return user.getUserId(); } @Override public String getPassword() { return user.getPassword(); } @Override public Collection<? extends GrantedAuthority> getAuthorities() { UserRoleEnum role = user.getRole(); String authority = role.getAuthority(); SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authority); Collection<GrantedAuthority> authorities = new ArrayList<>(); authorities.add(simpleGrantedAuthority); return authorities; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return false; } }
@Service @RequiredArgsConstructor public class UserDetailsServiceImpl implements UserDetailsService { private final UserRepository userRepository; @Override public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { User user = userRepository.findByUserId(userId) .orElseThrow(() -> new UsernameNotFoundException("NOT FOUND" + userId)); return new UserDetailsImpl(user); } }
- service 패키지
더보기BoardService
CommentService@Service @RequiredArgsConstructor public class BoardService { private final BoardRepository boardRepository; private final UserRepository userRepository; public Board createBoard(BoardRequestDto requestDto, User user) { String title = requestDto.getTitle(); String contents = requestDto.getContents(); Board board = new Board(title, contents, user); boardRepository.save(board); return board; } public List<Board> getAllBoards() { return boardRepository.findAll(); } public Board getBoardById(Long boardNum) { Board board = boardRepository.findById(boardNum) .orElseThrow(() -> new IllegalArgumentException("ID에 해당하는 게시물을 찾을 수 없습니다: " + boardNum)); return boardRepository.findById(boardNum).orElseThrow(() -> new IllegalArgumentException("없는 게시글 입니다.")); } public List<BoardResponseDto> getUserAllBoards(UserDetailsImpl userDetails) { User user = userRepository.findByUserId(userDetails.getUsername()) .orElseThrow(() -> new IllegalArgumentException("존재하는 회원이 없습니다.")); return boardRepository.findAllByUser(user) .stream().map(BoardResponseDto::new).toList(); } public BoardResponseDto getUserSelectedBoards(Long boardnum, UserDetailsImpl userDetails) { Board board = boardRepository.findById(boardnum) .orElseThrow(() -> new IllegalArgumentException("존재하는 게시물이 없습니다.")); if (!Objects.equals(userDetails.getUser().getUserNum(), board.getUser().getUserNum())) { throw new IllegalArgumentException("로그인 정보와 다른 게시물을 선택하였습니다."); } return new BoardResponseDto(board); } @Transactional public Board updateBoard(Long boardNum, BoardUpdateDto requestDto, User user) { Board board = findOne(boardNum); if (!board.getUser().equals(user)) { throw new IllegalArgumentException("작성자만 수정 할 수 있습니다."); } board.updateBoard(requestDto); return board; } public void deleteBoard(Long boardNum, User user) { Board board = findOne(boardNum); if (!board.getUser().equals(user)) { throw new IllegalArgumentException("작성자만 삭제 할 수 있습니다."); } boardRepository.delete(board); } private Board findOne(Long boardNum) { return boardRepository.findById(boardNum).orElseThrow(() -> new IllegalArgumentException("없는 게시글 입니다.")); } }
UserService@Service @RequiredArgsConstructor public class CommentService { private final CommentRepository commentRepository; private final BoardRepository boardRepository; private final UserRepository userRepository; public Comment addComment(Long boardNum, CommentRequestDto requestDto, User user) { Board board = findBoard(boardNum); User findUser = findUser(user); return commentRepository.save(new Comment(requestDto, board, findUser)); } public Comment updateComment(Long boardNum, Long commentNum, CommentRequestDto commentRequestDto, User user) { findBoard(boardNum); User findUser = findUser(user); Comment comment = findComment(commentNum); if(!comment.getUser().equals(findUser)) { throw new IllegalArgumentException("작성자만 수정 할 수 있습니다."); } comment.updateComment(commentRequestDto); return comment; } public void deleteComment(Long boardNum, Long commentNum, User user) { findBoard(boardNum); User findUser = findUser(user); Comment comment = findComment(commentNum); if(!comment.getUser().equals(findUser)) { throw new IllegalArgumentException("작성자만 삭제 할 수 있습니다."); } commentRepository.delete(comment); } public List<CommentResponseDto> getCommentsByBoard(Long boardNum) { Board board = findBoard(boardNum); List<Comment> commentList = commentRepository.findByBoardBoardNum(boardNum); return convertToDtoList(commentList); } private Board findBoard(Long boardNum) { return boardRepository.findById(boardNum).orElseThrow(() -> new IllegalArgumentException("없는 게시글입니다.")); } private User findUser(User user) { return userRepository.findById(user.getUserNum()).orElseThrow(() -> new IllegalArgumentException("없는 사용자입니다.")); } private Comment findComment(Long commentNum) { return commentRepository.findById(commentNum).orElseThrow(() -> new IllegalArgumentException("없는 댓글입니다.")); } private List<CommentResponseDto> convertToDtoList(List<Comment> commentList) { List<CommentResponseDto> commentResponseDtoList = new ArrayList<>(); for (Comment comment : commentList) { commentResponseDtoList.add(new CommentResponseDto(comment)); } return commentResponseDtoList; } }
@Service @RequiredArgsConstructor public class UserService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; private final BoardRepository boardRepository; private final CommentRepository commentRepository; private final JwtUtil jwtUtil; public void signup(SignupRequestDto requestDto) { String userId = requestDto.getUserId(); Optional<User> checkUserId = userRepository.findByUserId(userId); if (checkUserId.isPresent()) { throw new IllegalArgumentException("중복된 아이디가 존재합니다."); } String password = passwordEncoder.encode(requestDto.getPassword()); String email = requestDto.getEmail(); Optional<User> checkEmail = userRepository.findByEmail(email); if (checkEmail.isPresent()) { throw new IllegalArgumentException("중복된 이메일이 존재합니다."); } String name = requestDto.getName(); UserRoleEnum role = UserRoleEnum.USER; User user = new User(userId, password, email, name, role); userRepository.save(user); } public LoginResponseDto login(LoginRequestDto requestDto) { Optional<User> user = userRepository.findByUserId(requestDto.getUserId()); if (user.isEmpty()) { throw new IllegalArgumentException("존재하지 않는 회원입니다."); } if (!passwordEncoder.matches(requestDto.getPassword(), user.get().getPassword())) { throw new IllegalArgumentException("비밀번호가 다릅니다."); } String token = jwtUtil.createToken(user.get().getUserId(), UserRoleEnum.USER); LoginResponseDto responseDto = LoginResponseDto.builder() .userId(user.get().getUserId()) .password(user.get().getPassword()) .email(user.get().getEmail()) .name(user.get().getName()) .token(token) .build(); return responseDto; } public void deleteUser(User user) { User findUser = findUser(findUser(user)); if(!user.getUserNum().equals(findUser.getUserNum())) { throw new IllegalArgumentException("유저 정보가 일치하지 않습니다."); } List<Board> userBoards = boardRepository.findByUser(user); for(Board board : userBoards) { List<Comment> boardComments = commentRepository.findByBoard(board); commentRepository.deleteAll(boardComments); } boardRepository.deleteAll(userBoards); userRepository.delete(user); } public ProfileResponseDto getProfile(Long userNum) { User user = userRepository.findById(userNum).orElseThrow(() -> new IllegalArgumentException("해당 아이디는 존재하지 않습니다.")); return new ProfileResponseDto(user.getName(), user.getUserId(), user.getEmail(), user.getPassword()); } @Transactional public ProfileResponseDto updateProfile(Long userNum, UserUpdateDto request) { User user = userRepository.findById(userNum).orElseThrow(() -> new IllegalArgumentException(" 계정 정보가 일치하지 않습니다.")); if (!request.getPassword().equals(request.getConfirmPassword())) { throw new RuntimeException("패스워드가 일치하지 않습니다."); } String changedPassword = passwordEncoder.encode(request.getPassword()); user.updateProfile(request.getName(), request.getUserId(), request.getEmail(), changedPassword); return new ProfileResponseDto(user.getName(), user.getUserId(), user.getEmail(), changedPassword); } private User findUser(User user) { return userRepository.findById(user.getUserNum()).orElseThrow(() -> new IllegalArgumentException("없는 사용자입니다.")); } }
- util 패키지
더보기JwtUtil
@Component public class JwtUtil { public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String AUTHORIZATION_KEY = "auth"; // 권한 사용할 때 필요 public static final String BEARER_PREFIX = "Bearer"; private final long TOKEN_TIME = 60 * 60 * 1000L; // 60분 @Value(("${jwt.secret.key}")) private String secretKey; private Key key; private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; public static final Logger logger = LoggerFactory.getLogger("JWT 관련 로그"); @PostConstruct public void init() { byte[] bytes = Base64.getDecoder().decode(secretKey); key = Keys.hmacShaKeyFor(bytes); } public String createToken (String userId, UserRoleEnum role) { Date date = new Date(); return BEARER_PREFIX + Jwts.builder() .setSubject(userId) .claim(AUTHORIZATION_KEY, role) .setExpiration(new Date(date.getTime() + TOKEN_TIME)) .setIssuedAt(date) .signWith(key, signatureAlgorithm) .compact(); } public String getJwtFromHeader (HttpServletRequest req) { String bearerToken = req.getHeader(AUTHORIZATION_HEADER); if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(BEARER_PREFIX)) { return bearerToken.substring(7); } return null; } public boolean validateToken (String token) { try { Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token); return true; } catch (SecurityException | MalformedJwtException | SignatureException e) { logger.error("Invalid JWT Signature, 유효하지 않는 JWT 서명입니다."); } catch (ExpiredJwtException e) { logger.error("Expired JWT Token, 만료된 JWT 토큰입니다."); } catch (UnsupportedJwtException e) { logger.error("Unsupported JWT Token, 지원되지 않는 JWT 토큰입니다."); } catch (IllegalArgumentException e) { logger.error("JWT Claims is Empty, 잘못된 JWT 토큰입니다."); } return false; } public Claims getUserInfoFromToken (String token) { return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody(); } }
회고
- 이번 프로젝트로 인해 말로만 들었던 문제들을 직접 겪어보고 그 중요성을 더욱 크게 깨닫게 되는 시간이라 생각합니다.
- 또한 프로젝트를 통해 얻게 된 지식들이 너무 많고 직접 코드를 작성하며 깨닫는 것이 더 많은 것을 얻어가는 것 같습니다.
- 코드의 흐름을 알게 되고 문제를 해결하는 방법, 팀원과의 소통 등 너무 많은 것을 느끼고 얻어가는 시간이었습니다.
'Project > Newsfeed Project' 카테고리의 다른 글
[Project / Newsfeed] - 뉴스피드 프로젝트 5일차 (0) | 2024.02.18 |
---|---|
[Project / Newsfeed] - 뉴스피드 프로젝트 4일차 (0) | 2024.02.13 |
[Project / Newsfeed] - 뉴스피드 프로젝트 3일차 (0) | 2024.02.09 |
[Project / Newsfeed] - 뉴스피드 프로젝트 2일차 (0) | 2024.02.09 |
[Project / Newsfeed] - 뉴스피드 프로젝트 1일차 (0) | 2024.02.07 |