콘텐츠를 불러오는 중입니다.
다크 모드, Log 댓글, About 타임라인을 추가하고 댓글 삭제 버그와 헤더 Admin 링크 권한 노출을 고친 기록
사이트에 다크 모드가 없었고, Log 게시글에는 댓글을 달 방법이 없었습니다. About 페이지의 경력 소개는 실제 이력이 아닌 자리표시자 텍스트였고, 헤더의 관리자 진입 링크는 로그인 여부만 확인하고 있었습니다.
다크 모드를 넣는 김에, 옆에 밀려 있던 About 페이지 자리표시자 텍스트와 Log 댓글 기능도 함께 정리하기로 했습니다. 그 과정에서 발견한 버그 두 가지(댓글 삭제 오류, 헤더 Admin 링크 권한 노출)도 같은 작업 범위에서 고쳤습니다.
AuthNavLink가 "로그인했는지"만 확인해서, 일반 회원(user_roles가 자동 생성되는 'member' 계정)도 로그인만 하면 헤더에 Admin 링크가 보였습니다. /admin 서버 쪽 접근 제어는 항상 정상 동작하고 있었지만, 화면에 불필요한 링크가 노출되는 문제였습니다.log_comments 테이블과 RLS(누구나 공개 글 댓글 조회, 로그인한 회원만 자신의 댓글 작성, 작성자 또는 관리자만 삭제)addLogComment가 클라이언트 임시 id 대신 DB에 실제로 삽입된 행을 그대로 반환하도록 변경window.confirm()에서 관리자 화면의 <dialog> 확인 패턴을 재사용한 ConfirmButton으로 교체AuthNavLink가 로그인 여부에 더해 user_roles를 직접 조회해 role='admin'일 때만 Admin 링크를 보여주도록 변경.admin-form-row 정렬 버그, 사이드바 하단 링크 글자 크기 수정색상은 처음부터 CSS 변수로 관리하고 있어서, 다크 모드는 루트 토큰만 다시 정의하는 것으로 대부분 해결됐습니다. 댓글은 임시 id로 화면을 먼저 채우는 대신 서버가 실제로 만든 행을 반환받아 화면 상태를 덮어쓰는 방식으로 바꿔, 화면과 DB의 id가 항상 같도록 만들었습니다.
서버 권한 검사와 화면에 무엇을 보여줄지는 서로 다른 문제입니다.
Admin 링크는 /admin 서버 쪽에서 이미 안전하게 막고 있었지만, 그것과 별개로 권한 없는 사람에게 관리자 링크를 보여주는 것 자체가 혼란을 줄 수 있어 화면도 실제 데이터를 근거로 판단하도록 맞췄습니다.
댓글처럼 "로그인한 사람만 쓸 수 있고, 본인 것만 지울 수 있는" 규칙은 화면 쪽 코드로만 막으면 개발자 도구로 우회할 수 있습니다. Supabase의 RLS(Row Level Security)는 이 규칙을 데이터베이스 단에 걸어두는 방식이라, 어떤 경로로 요청이 오든 DB가 스스로 허용·거부를 판단합니다.
npm run format:checknpm run lintnpm run type-checknpm run buildsrc/styles/globals.csssrc/app/layout.tsxsrc/components/ui/ThemeToggle.tsxsrc/app/admin/layout.tsxsrc/app/(site)/about/page.tsxsrc/app/(site)/log/[slug]/actions.tssrc/components/log/CommentSection.tsxsrc/components/ui/ConfirmButton.tsxsrc/components/auth/AuthNavLink.tsxsrc/lib/comments-db.tssupabase/migrations/20260913100000_create_log_comments.sqlVercel 배포본에서 로그인·댓글 작성/삭제·다크 모드 흐름의 실제 운영 검증은 아직 하지 않았습니다.
Vercel에서 이번 변경들을 운영 검증하고, 카테고리 관리 UI와 Tech Radar 자동 수집 실행 방식을 다음 라운드에서 설계합니다.
댓글 0개
아직 댓글이 없습니다. 첫 댓글을 남겨보세요.
로그인 후 학습 기록에 댓글을 남길 수 있습니다.