728x90 반응형 전체 글104 사용자 인증 자격 증명 - Authorization header Authorization 헤더는 클라이언트 (브라우저나 앱)가 서버에 인증된 사용자라는 것을 증명하기 위해 요청할 때 사용하는 HTTP헤더이다. 서버는 사용자의 요청을 받을 때 이 요청을 보낸 사람이 누구인지, 권한이 있는지 알아야 하는데 AAuthorization 헤더에 포함된 토큰을 읽고 그 토큰이 유효한지 검사한다. | Frontend에서 사용 axios요청에 Authorization 헤더를 추가하는 예시이다. const token = localStorage.getItem('token');const res = await axios.put( `http://localhost:5000/api/posts/${id}`, { title, content }, { headers: { Auth.. 2025. 5. 7. 게시글 수정 페이지 작성 및 삭제 추가 - EditpostPage, PostDetailPage 수정/삭제는 게시글을 작성한 사용자만 접근이 가능하게 한다. 그러기 위해서는 이전에 만든 AuthContext를 사용한다.또한, axios요청에 headers: { Authorization: `Bearer ${token}` }로 인증된 사용자라는 것을 증명하게 한다. Authorization 헤더에 대해 자세히 알기> | 게시글 수정 페이지 작성이전에 작성한 게시글을 불러와 수정이 가능하게 하기 위해 새로운 파일을 만들어 작성한다. frontend/src/pages/EditPostPage.jsimport React, { useState, useEffect, useContext } from 'react';import axios from 'axios';import { useParams, useNavig.. 2025. 5. 7. 게시글 수정, 삭제 기능 추가하기 - postController 이제, 게시글을 수정하거나 삭제하는 기능이 필요하다.백엔드에서 해야 할 작업은 게시판 관련 컨트롤러에 기능을 추가하고 라우터만 추가하면 된다. | 게시글 수정/삭제 기능 추가 backend/controllers/postController.js// 글 수정exports.updatePost = async (req, res) => { try { const post = await Post.findById(req.params.id); if (!post) return res.status(404).json({ message: '게시글 없음' }); if (post.author.toString() !== req.user.id) return res.status(403).json({ messa.. 2025. 5. 7. 프론트엔드 기능별 라우터 분리 - routes/ 프로젝트를 진행하면서 점점 늘어나는 기능들을 더 효율적으로 관리하기 위해 App.js에 있는 라우터를 분리해주는 작업이 필요하다. 모듈화해서 나누면 각 기능들을 독립적으로 관리할 수 있고 가독성도 좋아져 체계적이다. 공동 처리나 확장시에도 적용하기가 쉬워진다. | 프론트엔드 라우터 구조 src/ routes/ AuthRoutes.js PostRoutes.js DashboardRoutes.js index.js ← App.js에 연결되는 최상위 통합 라우터 | 기능별 라우트 분할 frontend/routes/authRoutes.jsimport React from 'react';import { Route } from 'react-router-dom';import LoginPage .. 2025. 5. 6. 게시판 페이지 작성 - PostListPage, PostDetailPage, CreatePostPage 이미 backend 구현을 마치고 회원가입, 로그인까지 구현을 마쳤으니 기본적인 게시판을 만들어보려한다. | 게시판 목록 페이지 작성 - 백엔드의 /api/posts에 요청해 게시글 목록을 가져온다.- 제목, 작성자, 작성일을 보여준다.- 제목을 클릭하면 해당 게시글 상세 페이지로 이동한다. frontend/pages/PostListPage.jsimport React, { useEffect, useState } from 'react';import axios from 'axios';import { Link } from 'react-router-dom';const PostListPage = () => { const [posts, setPosts] = useState([]); const [loading,.. 2025. 5. 6. 윈도우 키보드에서 이모지(이모티콘) 입력하기 Windows 키보드에서 Win + . (윈도우 키와 마침표)를 동시에 누르면 아래와 같은 이모지 목록이 뜬다. 너무 간단하지만 모르면 못쓰니까.또.. 까먹을까봐 😊😁👍 2025. 5. 6. 전역 상태 관리하기 - AuthContext, 로그아웃 기능 context는 React에서 전역 상태 관리를 가능하게 해주는 도구이다.props를 컴포넌트 계층을 따라 계속 전달하지 않고 공통적으로 필요한 데이터를 한 곳에서 관리하고 사용할 수 있다. 지금까지는 로그인 성공 후 navigate()만 했고 사용자 정보를 다른 컴포넌트에서 사용하지 않았기 때문에 필요하지 않았지만 여러 곳에서 로그인한 사용자의 정보를 유지 관리하려면 필요하다. React Context는- 로그인한 사용자 정보 ( user )- 로그인 상태 여부 ( isAuthenticated )- token- 로그아웃 함수 등 앱 전역에서 쉽게 접근하고 사용할 수 있도록 만든다. | context 디렉터리 구조frontend/└── src/ └── context/ └── AuthC.. 2025. 5. 5. 로그인 응답 구조로 인해 발생한 오류 "undefined" is not valid JSON 로그인을 해야 접근이 가능하도록 구현을 하는 중이다.직전에 로그인 시 접근 가능한 기본 페이지를 만들고 라우터에 적용하는 것까지 마쳤는데 서버 실행 후 로그인에 정보를 입력하니 이와 같은 오류가 떴다. | SyntaxError: "undefined" is not valid JSON "undefined" is not valid JSON는 JSON.parse()에 넘긴 값이 "undefined" (문자열 "undefined" 또는 실제 undefined)일 때 발생한다. 즉, localStorage.getItem('user')가 undefined인데도 JSON.parse()를 실행했기 때문. DeshboardPage.js의 아래 코드에서 문제가 발생된 것으로 보인다.const user = JSON.parse.. 2025. 5. 4. 인증이 필요한 보호 페이지 - ProtectedRoute, DashboardPage 로그인 후에만 접근 가능한 보호 페이지이다. 사용자가 로그인 상태일 때만 접근이 가능하고 로그인이 되어있지 않으면 강제로 로그인페이지로 이동시킨다.또, localStorage를 사용해 새로고침을 해도 로그인 상태를 유지하게 한다. | 컴포넌트 만들기 frontend/src/components/ProtectedRoute.jsimport React from 'react';import { Navigate } from 'react-router-dom';const ProtectedRoute = ({ children }) => { const token = localStorage.getItem('token'); return token ? children : ;};export default ProtectedRou.. 2025. 5. 4. 로그인 기능 구현 - LoginPage 이제 로그인 페이지의 기능을 추가할 차례다. | 로그인 요청 서버로 전송하고 성공시 JWT저장하는 로직 추가 frontend/src/pages/LoginPage.js const handleSubmit = async (e) => { e.preventDefault(); try { const res = await axios.post('http://localhost:5000/api/auth/login', formData); localStorage.setItem('token', res.data.token); // JWT 저장 setMessage('로그인 성공! 🎉'); console.log(res.data); // 디버깅용 } catch (err) { .. 2025. 5. 4. 이전 1 2 3 4 5 ··· 11 다음 728x90 반응형