본문 바로가기
개발/Spring

[SpringBoot] React + TypeScript + JPA 프로젝트 (7) - 게시판 만들기(글 작성)

by 코딩하는 흰둥이 2024. 11. 8.

이전글

https://greed-yb.tistory.com/309

 

[SpringBoot] React + TypeScript + JPA 프로젝트 (6) - 게시판 만들기(페이징 처리)

이전글https://greed-yb.tistory.com/308 [SpringBoot] React + TypeScript + JPA 프로젝트 (5) - 게시판 만들기(목록)이전글https://greed-yb.tistory.com/307 [SpringBoot] React + TypeScript + JPA 프로젝트 (4) - 회원가입, 로그인 하

greed-yb.tistory.com

 

 

 

 

board.tsx

...
...
...
<div className="card">
    <div className="card-body">
        <h5 className="card-title">게시판 목록</h5>
        <Link to="/boardWrite" className="btn btn-dark" type="button" style={{float:"right"}}>글 작성</Link>

        <table className="table datatable">
            <thead>
            <tr>
                <th>
                    No
                </th>
                ...

 

 

 

 

boardWriter.tsx

Bootstrap 에 있던 forms-layouts.html 에서 원하는 form 을 boardWriter.tsx 로 만들었다

 

import React, {useEffect, useState} from "react";
import axios from "axios";
import {Link} from "react-router-dom";
import Cookies from 'js-cookie';


// 게시판 변수 타입 설정
interface BoardWrite {
    title: string;
    contents: string;
}

function BoardWrite() {

    const [data, setData] = useState<BoardWrite[]>([]);

    // 태그의 name 을 인식해서 값을 가져온다
    const dataCheck = (event: { target: { value: string; name: string; }; }) => {
        const { value, name } = event.target;
        setData({
            ...data,
            [name] : value,
        })
    }

    const axiosSave : () => Promise<void> = async () => {

        const token = document.cookie;
        if (!token){
            // token 이 없다면 로그인 화면으로
            window.location.href = '/login';
        }else{
            // npm install js-cookie
            // npm install @types/js-cookie
            // Cookies 에서 바로 token 을 가져올 수 있게 js-cookie 를 설치해서 사용하였다
            let checkToken : string | undefined = "";
            if(!Cookies.get('refreshToken')){
                // refreshToken 이 없다면 로그인 화면으로
                window.location.href = '/login';
            }else{
                checkToken = Cookies.get('refreshToken')
            }

            await axios.post("http://localhost:7172/api/boardSave" , data ,{
                params: {checkToken}
                }
            ).then((response) => {
                if(response.data == "success"){
                    alert("저장하였습니다.");
                    window.location.href = '/board';
                }
            }).catch((error) => {
                alert("저장 실패하였습니다.");
            })
        }
    }

    return (
        <main id="main" className="main">

            <div className="pagetitle">
                <h1>게시판</h1>
                <nav>
                    <ol className="breadcrumb">
                        <li className="breadcrumb-item"><Link to="/">Home</Link></li>
                        <li className="breadcrumb-item">Forms</li>
                        <li className="breadcrumb-item active">Layouts</li>
                    </ol>
                </nav>
            </div>


            <section className="section">
                <div className="row">
                    <div className="col-lg-6">
                        <div className="card">
                            <div className="card-body">
                                <h5 className="card-title">글 작성</h5>

                                <form className="row g-3">
                                    <div className="col-12">
                                        <label htmlFor="inputNanme4" className="form-label">제목</label>
                                        <input type="text" className="form-control" id="title" name="title" onChange={dataCheck}/>
                                    </div>
                                    <div className="col-12">
                                        <label htmlFor="contents" className="form-label">내용</label>
                                        <textarea className="form-control" id="contents" name="contents" style={{height: "200px"}} onChange={dataCheck}></textarea>
                                    </div>
                                    <div className="text-center">
                                        <button type="button" className="btn btn-primary" onClick={axiosSave}>저장</button>
                                        <Link to="/board" className="btn btn-secondary">뒤로</Link>
                                    </div>
                                </form>

                            </div>
                        </div>

                    </div>
                </div>
            </section>
        </main>

    );
}

export default BoardWrite;

 

Token 정보를 가져와서 인증체크를 하고

refreshToken 을 Controller 로 보내서 Token 에서 username 을 추출하려한다

npm install js-cookie
npm install @types/js-cookie

 

Token 정보를 쉽게 가져올 수 있도록 라이브러리를 설치 하였다

 

 

BoardController
import com.example.reactpractice.repository.board.BoardRepository;
import com.example.reactpractice.security.JwtTokenUtil;
import com.example.reactpractice.vo.boardVo.BoardVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


import java.util.List;

@RestController
@RequestMapping("/api/*")
public class BoardController {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private BoardRepository boardRepository;

    @GetMapping("/boardList")
    public List<BoardVo> boardList(@RequestParam String searchOption , @RequestParam String search) throws Exception{

        List<BoardVo> vo = boardRepository.search(searchOption, search);
        return vo;
    }

    @PostMapping("/boardSave")
    public String boardSave(@RequestBody BoardVo vo, @RequestParam String checkToken) throws Exception{

        try {
            // refreshToken 에서 사용자의 username 을 가져온다
            String username = jwtTokenUtil.getUsernameFromRefreshToken(checkToken);
            vo.setNo(158L);
            vo.setWriter(username);
            boardRepository.save(vo);
            return "success";
        }catch (Exception e){
            e.printStackTrace();
            return "유효하지 않은 사용자";
        }
    }

}

 

 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 값 자동 생성
    private Long no;

vo.setNo 의 경우 자동 증가 설정을 해놨는데

Oracle 에서 적용이 안되어 테스트 만 진행하기 위해

@GeneratedValue 을 제거하고 임의로 값을 넣어주었다

본인의 DB 에 맞춰서 적용 시키길 바란다

 

 

 

 

TEST

 

 

 

 

 

 


security 가 제대로 적용되지 않고 있는 상태다 보니

현재 사용자의 정보를 받아오지 못하는 상황이 되었다

 

Jwt Token 에 username 이 같이 들어있어서 

Token 에서 추출하여 사용하는 방식으로 하게 되었는데 

설계부터 현재 진행 방식까지 마음에 들지 않는다...

 

글 저장 할때 refreshToken 만 체크하여 Controller 로 전송하였는데

accessToken 부터 체크 하는게 맞다고 생각한다

refreshToken 이 없는 경우는 token 정보를 건들였다 라는 전제로 테스트겸 진행하였다

 

 

 

댓글