무료 강의 · 시즌 5 · 3강 / 5
나만 쓸 수 있는 글쓰기
무료 강의 시즌 5의 3강. 로그인을 붙이고, 화면을 우회해도 데이터베이스가 막는 걸 직접 확인해요. 숨김과 잠금은 다릅니다.
끝나면 손에 남는 것: 로그인한 나만 글을 쓰는 블로그 + "숨김과 잠금은 다르다"는 감각
이 강의 완성 예시 열어보기우회 시도가 거부되는 실제 응답과, 로그인 후 성공 화면이에요.지난 강의에서 글이 장부(데이터베이스)로 이사했어요. 그런데 글을 쓰려면 아직 Supabase 화면까지 가야 하죠. 내 블로그 안에 글쓰기 화면이 필요해요.
여기서 문제가 하나 생겨요. 글쓰기 화면을 만들면, 그 화면은 인터넷에 있는 모두에게 열려요. 아무나 내 블로그에 글을 쓸 수 있게 되는 거죠.
식당으로 치면 이래요. 손님은 홀까지만 들어와요. 주방에 들어가려면 출입증이 있어야 하고요. 오늘 그 출입증을 만듭니다. 그리고 더 중요한 것 — 출입증 검사를 누가 하는지 배워요.
오늘 만들 것
로그인한 나만 글을 쓸 수 있는 블로그.
그리고 이 시즌에서 제일 중요한 문장 하나: 버튼을 숨기는 것과 금고를 잠그는 것은 다르다.
준비물
- 시즌 5의 2강을 마친 상태 (블로그가 데이터베이스에서 글을 읽어요)
- 45분
- 내 이메일 주소와, 새로 만들 비밀번호 하나
따라 하기
1. 출입증 발급소를 확인해요
Supabase 대시보드에서 Authentication(인증) 메뉴를 여세요. 이메일+비밀번호 로그인은 기본으로 켜져 있어요. 설정에서 바꿀 건 없어요 — 확인만 하고 갑니다.
비밀번호가 걱정되나요? 좋은 걱정이에요. 안심해도 되는 이유를 말할게요. 비밀번호는 Supabase가 암호화해서 보관하고, 우리 코드는 비밀번호를 저장하지 않아요. 로그인을 전문 서비스에 맡긴다는 건 정확히 이걸 맡긴다는 뜻이에요. 이 사이트(에이전트 키친)의 회원 가입도 같은 원칙으로 만들어져 있어요.
2. 내 출입증을 만들어요
가입 화면은 안 만들 거예요. 1인 블로그에 가입 화면이 있으면 아무나 계정을 만들 수 있게 되니까요. 시즌 4에서 배운 그대로예요 — 만들지 않기로 정하는 것도 설계예요.
대신 대시보드에서 직접 만듭니다. Authentication → Users → Add user → Create new user를 누르고, 내 이메일과 새 비밀번호를 넣으세요. 폼에 "Auto confirm user?" 체크가 기본으로 켜져 있는데 그대로 두세요 — 확인 메일 없이 계정이 바로 활성화된다는 뜻이에요. 폼 아래에도 그렇게 적혀 있어요("A confirmation email will not be sent").
이 비밀번호는 오늘 새로 만든, 이 블로그 전용이에요. 다른 데서 쓰는 비밀번호를 재사용하지 마세요.
3. 로그인과 글쓰기 화면을 시켜요
내 블로그에 "나만 쓸 수 있는 글쓰기"를 붙일 거야. Supabase Auth의
이메일+비밀번호 로그인을 쓴다. 계정은 대시보드에서 이미 만들었어.
만들 것:
- login.html : 이메일/비밀번호 입력 → 로그인. 실패하면 "이메일 또는
비밀번호가 맞지 않아요"만 보여 줘 (자세한 이유는 숨겨)
- write.html : 로그인된 사람만 쓰는 새 글 작성 폼(제목/요약/본문).
저장하면 posts 테이블에 들어가고 홈으로 이동
- write.html에 로그인 안 된 채 들어오면 login.html로 보내
- 홈(index.html) 오른쪽 위에, 로그인 상태일 때만 "글쓰기" 링크가 보이게
- 로그아웃 버튼도 write.html에 넣어 줘
그리고 RLS 쓰기 정책 SQL을 따로 보여 줘:
- posts에 "로그인한 사용자만 insert 가능" 정책
- 나는 그것도 SQL Editor에 직접 붙여넣을 거야
중요: 링크를 숨기는 것은 편의일 뿐이고, 진짜 보안은 RLS 정책이라는 걸
코드 주석에 한 줄로 남겨 줘.
에이전트가 두 가지를 줘요. 코드(로그인·글쓰기 화면)와 SQL(쓰기 정책). SQL은 2강에서 한 것처럼 SQL Editor에 붙여넣고 Run하세요.
4. 먼저 정상 경로를 확인해요
login.html을 열고 아까 만든 이메일과 비밀번호로 로그인하세요. 홈으로 가면 오른쪽 위에 "글쓰기"가 보일 거예요.
글쓰기 화면에서 진짜 글을 한 편 쓰세요. 데모 글 말고, 오늘 데이터베이스를 연결한 소감이라도요. 저장하면 홈 목록 맨 위에 내 글이 올라와요.
Table Editor를 열어보세요. 방금 쓴 글이 표에 줄로 앉아 있어요. 이제 장부에 손으로 적지 않아도 돼요 — 블로그가 대신 적어요.
5. 오늘의 순간 — 우회해 봅니다
이제 진짜 시험이에요. 도둑 입장이 되어 볼 거예요.
시크릿 창(로그인이 안 된 깨끗한 브라우저)을 열고, 주소창에 write.html의 경로를 직접 쳐서 들어가 보세요.
로그인 화면으로 튕겨나갈 거예요. 좋아요. 그런데 이건 화면이 막은 것뿐이에요. 화면 코드는 방문자의 브라우저에서 도는 것이라, 마음먹은 사람은 우회할 수 있어요.
그러니 한 단계 더요. 에이전트에게 이렇게 시켜보세요.
로그인하지 않은 상태로 posts 테이블에 글을 강제로 insert 해 봐.
공개 키만 가지고, 우리 화면을 거치지 않고 직접. 결과를 그대로 보여 줘.
거부당해요. 에러 메시지에 정책 위반이라고 나올 거예요.
이게 오늘의 문장이에요. 화면(버튼 숨김)은 편의고, 정책(RLS)이 잠금이에요. 문 앞의 안내판은 넘어올 수 있지만, 금고는 열쇠 없이 안 열려요. 그리고 2강에서 했던 말이 완성돼요 — 공개 키를 코드에 넣어도 되는 이유는, 그 키로 할 수 있는 일을 정책이 정하기 때문이에요.
6. 저장점
git 저장점을 만들어 줘. 이름은 "로그인과 글쓰기".
막혔을 때
로그인이 계속 실패해요. 대시보드 Authentication → Users에서 계정이 실제로 만들어졌는지, 이메일에 오타가 없는지 보세요. 서버가 돌려주는 원래 에러는 "Invalid login credentials" 하나뿐이에요 — 이메일이 틀렸는지 비밀번호가 틀렸는지 알려주지 않는데, 그게 보안상 정상이에요(우리 로그인 화면도 그래서 뭉뚱그려 보여줘요).
로그인은 되는데 저장이 안 돼요. 쓰기 정책 SQL을 Run 했는지 확인하세요. 정책이 없으면 로그인해도 거부돼요 — 열쇠(로그인)가 있어도 문(정책)이 없으면 못 들어가요. 이상해 보이지만 이게 오늘 배운 그 원리예요. 에러 문구를 그대로 에이전트에게 주면 정확히 짚어줘요.
시크릿 창에서 write.html이 그냥 열려요. 튕기는 코드가 빠진 거예요. "write.html에 로그인 확인이 빠졌어. 로그인 안 된 상태면 login.html로 보내 줘." 다만 기억하세요 — 화면이 뚫려도 저장은 정책이 막아요. 5단계에서 확인한 그대로요.
"강제로 insert 해 봐"가 성공해버렸어요. 쓰기 정책이 제대로 안 붙은 거예요. 지금 발견해서 다행이에요 — 이게 이 실습을 하는 이유예요. "posts 테이블의 RLS 정책 전체를 보여주고, 로그인 없이 insert가 되는 구멍을 찾아서 고치는 SQL을 줘."
로그인 상태가 새로고침하면 풀려요. "로그인 상태가 유지되게 해 줘"라고 시키세요. supabase-js가 브라우저에 세션을 기억하게 되어 있어서 한 줄로 해결돼요.
마무리 체크
나가기 전에 하나씩 확인해요:
- 대시보드에서 내 계정을 만들었어요 (Auto confirm 켠 채로)
- 로그인 → 글쓰기 → 저장 → 홈 목록에 뜨는 걸 봤어요
- 내가 쓴 진짜 글 한 편이 Table Editor에 줄로 보여요
- 시크릿 창에서 write.html이 로그인으로 튕겼어요
- 화면을 우회한 강제 insert가 정책에 거부당했어요 ← 오늘의 순간
- git 저장점 "로그인과 글쓰기"를 만들었어요
이제 이 블로그는 읽기는 모두에게, 쓰기는 나에게만 열려 있어요.
그런데 블로그가 좋아지는 건 혼자 쓸 때가 아니라 읽은 사람이 말을 걸 때부터예요. 다음 강의에서 방문자에게 문을 하나 열어줍니다. 다만 이번엔 아무나 드나드는 문이라, 여는 법이 좀 달라요.
직접 만들고 돌아가는 걸 확인했나요? 그럼 완료를 눌러요. 이 브라우저에만 저장돼요 — 주방 밖으로는 아무것도 나가지 않아요.
다음 — 4강 · 방문자 댓글 받기 →