마트철수
[TIL_6] KB 부트캠프: CRUD 게시판 만들기 ?! 본문

안녕하세요,
'Today I Learned' 6주차에서는
CRUD로 구현한 게시판의 요약본에 대해
작성해보겠습니다.
실제 구현했던 게시판을 이해하는 데
가장 기초된 개념이였던 CRUD!
그리고 간단한 코드와 함께 최종 마무리를 지으려 합니다.
무엇보다 비전공자 관점에서
누구나 쉽게 게시물을 구현할 수 있도록 한 수업에 감사하며..
(KB 국민은행 주관 IT's Your Life)
그만큼 쉽게 포스팅도 남겨보겠습니다.
좀 더 세부적인 내용은 가장 하단의 타임라인을 참고해주세요!
목차
- CRUD 개념
- Spring(백엔드)
- Vue.js(프론트엔드)
- 게시판을 구현하며 느낀
현재 KB IT's Your Life에서 다루는 내용을 기반으로 작성하였으며,
하단엔 '~다' 체를 사용하였습니다.
#KB부트캠프 #KB코딩 #KB코딩테스트
1. CRUD 개념
- CRUD는 소프트웨어 애플리케이션에서 Create(생성), Read(읽기), Update(수정), Delete(삭제)의 약자
- 데이터베이스나 웹 애플리케이션의 기본적인 작업을 설명하는 용어
- 데이터 관리의 기본적인 작업으로, 대부분의 웹 애플리케이션이나 API에서 자주 사용됨

CRUD
- Create: 새로운 데이터를 추가하는 작업
- Read: 저장된 데이터를 조회하는 작업
- Update: 기존 데이터를 수정하는 작업
- Delete: 데이터를 삭제하는 작업
각 개념에 대해 간단한 코드
- Spring과 Vue.js를 사용:
// Controller 예시 (Spring Boot)
@PostMapping("/create")
public ResponseEntity<Post> createPost(@RequestBody Post post) {
Post savedPost = postService.createPost(post);
return ResponseEntity.ok(savedPost);
}
@GetMapping("/posts/{id}")
public ResponseEntity<Post> readPost(@PathVariable Long id) {
Post post = postService.getPostById(id);
return ResponseEntity.ok(post);
}
@PutMapping("/posts/{id}")
public ResponseEntity<Post> updatePost(@PathVariable Long id, @RequestBody Post postDetails) {
Post updatedPost = postService.updatePost(id, postDetails);
return ResponseEntity.ok(updatedPost);
}
@DeleteMapping("/posts/{id}")
public ResponseEntity<Void> deletePost(@PathVariable Long id) {
postService.deletePost(id);
return ResponseEntity.noContent().build();
}
- HTTP 메서드: CRUD는 보통 HTTP 메서드인 POST, GET, PUT, DELETE와 매핑
- REST API: RESTful 서비스에서 CRUD 작업은 리소스(예: 사용자, 게시물 등)에 대한 액션을 수행하는 데 사용
2. Spring (백엔드)
- Model 정의:
데이터베이스와 매핑되는 객체를 정의한다.
@Entity를 사용하여 데이터베이스 테이블과 연결된다. - DAO (Data Access Object):
Spring에서 데이터베이스에 접근하는 클래스를 작성한다.
JDBC나 Hibernate를 활용해 직접 쿼리를 작성하거나, JpaRepository 같은 인터페이스를 사용할 수 있다. - Service Layer:
비즈니스 로직을 담당하는 레이어이다.
여기서 DAO를 호출하고, 데이터를 처리하거나 검증하는 로직을 추가한다. - JWT 인증:
Spring Security와 JWT를 통합하여 사용자 인증을 처리한다.
Spring Security 설정을 통해 모든 요청을 보호하고, JWT 토큰을 검증하여 권한을 부여한다. - Controller:
사용자가 보내는 HTTP 요청을 처리하고, CRUD 및 인증 기능을 API 형태로 제공한다.
Spring의 계층 구조를 이해하면서 느낀 점은,
DAO와 Service 레이어의 분리는 비즈니스 로직과 데이터 접근의 독립성을 보장하여 유지보수에 매우 유리하다는 점! J그리고 WT와 Spring Security 를 활용한 인증은 보안성을 강화할 수 있고, 권한 관리가 유연하다는 것을 느꼈다.
1) JWT 설정 (Spring Security)
- Spring에서는 Spring Security와 JWT를 연동하여 인증 및 권한 관리를 할 수 있다.
먼저 JWT 토큰을 생성하고 검증하는 과정을 설정해야 한다. - JWT 생성 및 검증 로직:
public class JwtUtil {
private String SECRET_KEY = "secret";
// JWT 생성
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// JWT 검증
public boolean validateToken(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
}

2) Spring Security 설정 (SecurityConfig.java)
- SecurityConfig 클래스에서 Spring Security와 JWT를 연동하는 설정을 추가한다.
- 여기서, 특정 엔드포인트에 대해 JWT 인증을 요구할 수 있다.
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login", "/register").permitAll() // 인증 없이 접근 가능
.anyRequest().authenticated() // 나머지는 인증 필요
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// JWT 필터 추가
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}

3) CRUD 기능 구현
- CRUD 기능은 각각 게시물을 생성, 조회, 수정, 삭제하는 메서드로 구성된다.
- JWT를 사용하여 각 요청에 대해 사용자가 인증되었는지 확인하고, 그에 따라 권한을 부여한다.
// 게시물 생성 (Create)
@PostMapping("/posts")
public ResponseEntity<Post> createPost(@RequestHeader("Authorization") String token, @RequestBody Post post) {
if (!jwtUtil.validateToken(token)) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
postService.savePost(post);
return new ResponseEntity<>(post, HttpStatus.CREATED);
}
// 게시물 조회 (Read)
@GetMapping("/posts/{id}")
public ResponseEntity<Post> getPost(@PathVariable Long id) {
Post post = postService.findPostById(id);
return new ResponseEntity<>(post, HttpStatus.OK);
}
// 게시물 수정 (Update)
@PutMapping("/posts/{id}")
public ResponseEntity<Post> updatePost(@RequestHeader("Authorization") String token, @PathVariable Long id, @RequestBody Post postDetails) {
if (!jwtUtil.validateToken(token)) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
Post updatedPost = postService.updatePost(id, postDetails);
return new ResponseEntity<>(updatedPost, HttpStatus.OK);
}
// 게시물 삭제 (Delete)
@DeleteMapping("/posts/{id}")
public ResponseEntity<Void> deletePost(@RequestHeader("Authorization") String token, @PathVariable Long id) {
if (!jwtUtil.validateToken(token)) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
postService.deletePost(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}

3. Vue.js (프론트엔드)
- JWT를 사용한 인증 및 CRUD 작업:
JWT 토큰은 사용자가 로그인할 때 서버로부터 발급받으며, 이후 각 요청에서 토큰을 HTTP 헤더에 포함시켜 인증을 진행한다.
<template>
<div>
<h1>게시판</h1>
<form @submit.prevent="createPost">
<input v-model="newPost.title" placeholder="제목" />
<textarea v-model="newPost.content" placeholder="내용"></textarea>
<button type="submit">게시물 작성</button>
</form>
<div v-for="post in posts" :key="post.id">
<h2>{{ post.title }}</h2>
<p>{{ post.content }}</p>
<button @click="editPost(post)">수정</button>
<button @click="deletePost(post.id)">삭제</button>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
posts: [],
newPost: { title: '', content: '' },
};
},
methods: {
createPost() {
const token = localStorage.getItem('token');
axios.post('/api/posts', this.newPost, {
headers: { Authorization: `Bearer ${token}` }
}).then(response => {
this.posts.push(response.data);
});
},
deletePost(id) {
const token = localStorage.getItem('token');
axios.delete(`/api/posts/${id}`, {
headers: { Authorization: `Bearer ${token}` }
}).then(() => {
this.posts = this.posts.filter(post => post.id !== id);
});
},
editPost(post) {
// 수정 로직 추가
}
},
mounted() {
axios.get('/api/posts').then(response => {
this.posts = response.data;
});
}
};
</script>
Spring Framework를 사용하여 JWT 기반 인증과 CRUD 기능을 구현하면?!
보안성과 확장성이 뛰어난 애플리케이션을 만들 수 있다!
Vue.js로 게시판을 직접 꾸며보는 과정을 통해 직관적인 사용자 인터페이스를 제공할 수 있다!
위 게시판을 통해 직접 게시판을 꾸며보는 것을 추천 ex) hover 강조, background 이미지 변경 등
지금 제가 하고 있는 작업이기도 합니다.. 완료되면 티스토리에 올리고 싶음 ..

4. 구현된 기능 설명 추가
- JWT 기반 인증:
사용자는 로그인 시 JWT를 발급받으며, 이후 요청 시 해당 토큰을 헤더에 포함시켜 서버에서 인증을 받는다.
서버는 토큰을 검증한 후 요청을 처리한다. - CRUD 기능:
- 생성(Create): 게시물 생성 시 JWT를 이용한 사용자 인증을 통과한 후 게시물을 등록할 수 있다.
- 조회(Read): 인증된 사용자는 전체 게시물을 조회할 수 있다.
- 수정(Update): 사용자 권한에 따라 수정 권한을 부여받은 경우에만 게시물을 수정할 수 있다.
- 삭제(Delete): 사용자는 자신의 게시물만 삭제할 수 있으며, JWT 인증을 통해 권한을 확인한 후 삭제한다.
4. 느낀 점
- 느낀 점:
JWT를 통한 인증 시스템과 CRUD 게시판을 구현하면서 사용자 인증과 보안의 중요성을 크게 느꼈습니다. 특히, JWT를 활용해 인증된 사용자만 특정 기능을 사용할 수 있도록 제한하는 것이 굉장히 실용적이라는 생각이 들었습니다. (나만의 비밀 다이어리를 만드는데 유용하지 않을까 싶네요ㅎㅎ)
- 더 구현해보고 싶은 점:
현재 구현된 JWT는 기본적인 인증만 처리하고 있어, 토큰의 만료 시간 관리나 자동 재발급 기능이 추가적으로 필요하여, 이 부분도 수업 시간에 배웠습니다. 2차 보안 대신에 해당 보안을 더 강력히 할 수 있는 방안을 없을지 고민해보려고 합니다.
사용자 역할(예: 관리자, 일반 사용자)에 따른 권한 구분을 추가해보고 싶습니다. 예를 들어, 관리자는 모든 게시물을 삭제할 수 있지만, 일반 사용자는 자신의 게시물만 수정 및 삭제할 수 있는 권한을 주는 방식!!
- 어려웠던 점:
JWT 토큰 만료 후 재발급 과정에서 발생할 수 있는 보안 문제에 대한 고민이 있었습니다. 특히, 토큰이 만료된 경우 이를 자동으로 갱신하는 방법과, 갱신 과정에서 발생할 수 있는 보안 취약점을 해결하는 것이 어려웠습니다.
5. 컴포넌트 백엔드 교육 타임라인 정리
드디어 컴포넌트 백엔드 교육의 마지막 포스팅입니다!
2개의 포스팅으로 게시물 코드 구현을 마무리해보았습니다.
벌써 4개월이 시간이 지났다니.. 믿기지가 않네요..
👩💻타임라인
1일차. Spring+Vue: 게시판 프론트엔드 마무리
2024.09.02 - [KB IT's Your Life/교육] - [078] Spring+Vue: 게시판 프론트엔드 마무리
2일차. Spring+Vue: 게시판 수정
2024.09.03 - [KB IT's Your Life/교육] - [079] Spring+Vue: 게시판 수정
📒TIL을 마무리하며..
타임라인에 2개의 포스팅밖에 없는 이유는
게시판 개설을 마지막으로 팀프로젝트를 시작했기 때문입니다.
KB IT's Your Life에서는 전공반과 비전공반을 합쳐
최종 프로젝트를 진행하고 있습니다.
해당 프로젝트를 통해 그동안 배웠던 풀스택을 활용해보고,
금융 지식을 더욱 쌓을 수 있는 기회가 주어집니다.
다음 포스팅부터는 해당 프로젝트를 진행하면서 느낌점과
코드를 구현하며 어려웠던 개념을 더욱 깊게 알아볼 예정입니다.

'KB IT's Your Life > KB 기자단' 카테고리의 다른 글
| [TIL_8] KB 부트캠프: 카카오개발자 API 지도 불러오기(Vue, JAVA) (5) | 2024.09.24 |
|---|---|
| [TIL_7] KB 부트캠프: 비전공자가 개발 프로젝트 시작 (5) | 2024.09.15 |
| [TIL_5] KB 부트캠프: Spring과 Vue로 연동하기 (6) | 2024.09.01 |
| [TIL_4] KB 부트캠프: JWT (0) | 2024.08.26 |
| [TIL_3] KB 부트캠프: REST API (5) | 2024.08.18 |