여러분, 아침에 은행 앱을 켜서 로그인하면 앱이 대뜸 "김부장님 안녕하세요" 하고 제 이름을 부릅니다. 저는 방금 비밀번호 여섯 자리 눌렀을 뿐인데, 앱은 어떻게 그 수많은 사람 중에 저를 정확히 알아보는 걸까요? 그리고 저는 제 계좌는 마음대로 이체하는데, 옆 사람 계좌는 조회조차 안 됩니다. 앱은 대체 뭘 근거로 "이건 이 사람이 해도 되고, 저건 안 된다"를 판단할까요?

저는 코딩을 늦게 시작한 사람입니다. 처음엔 이런 게 그냥 마법처럼 느껴졌어요. 그런데 알고 보니 이 뒤에는 딱 두 가지 질문이 숨어 있더군요. "너 누구니?" 그리고 "너 그거 해도 되니?" 이 두 질문에 답하는 기술이 각각 인증(Authentication)인가(Authorization)입니다. 이름이 비슷해서 헷갈리는데, 오늘 이걸 확실하게 갈라드릴게요.

그리고 하나 더. 브라우저 주소창 왼쪽에 붙어 있는 작은 자물쇠 모양 보신 적 있죠? 그게 바로 HTTPS입니다. 이 자물쇠가 없으면, 여러분이 입력한 비밀번호가 인터넷을 지나는 동안 중간에서 훤히 보일 수 있어요. 오늘은 이 자물쇠가 무슨 일을 하는지, 그리고 로그인이라는 게 뒤에서 실제로 어떻게 굴러가는지를, 코드 최소한으로 편지와 자물쇠 이야기로 천천히 풀어보겠습니다. 겁먹지 마세요. 저도 그랬으니까요.

웹 보안의 핵심은 세 가지 질문입니다. 편지를 남이 못 훔쳐보게 봉인했는가(HTTPS), 너 누구니(인증), 그건 해도 되니(인가). 이 셋만 구분하면 오늘 글의 절반은 이해하신 겁니다.

먼저 전체 그림부터 — 로그인 한 번에 벌어지는 일

구체적인 설명에 들어가기 전에, 여러분이 어떤 사이트에 로그인 버튼을 눌렀을 때 뒤에서 무슨 일이 순서대로 일어나는지 큰 그림을 먼저 보여드릴게요. 이 흐름만 머릿속에 넣어두시면, 뒤에 나오는 용어들이 "아, 그게 여기 나오는 거였구나" 하고 제자리를 찾아갑니다.

봉인
HTTPS 암호화
너 누구니?
인증
출입증 발급
세션/토큰
그건 해도 돼?
인가

순서대로 풀면 이렇습니다. ①먼저 여러분이 아이디·비밀번호를 입력해 서버로 보낼 때, 그 내용이 중간에서 도둑맞지 않도록 HTTPS로 봉인해서 보냅니다. ②서버는 봉인을 열어 비밀번호가 맞는지 확인하고 "이 사람은 김부장이 맞다"고 판단합니다. 이게 인증이에요. ③그러면 서버는 여러분에게 일종의 출입증(세션 또는 토큰)을 하나 발급합니다. 다음부터는 매번 비밀번호를 다시 묻지 않고 이 출입증만 보면 되니까요. ④그리고 여러분이 어떤 기능을 쓰려 할 때마다, 서버는 그 출입증을 보고 "이 사람이 이걸 해도 되는 등급인가?"를 확인합니다. 이게 인가입니다.

이 네 단계가 오늘 글의 뼈대입니다. 하나씩 천천히 살펴보죠.

HTTP vs HTTPS — 엽서와 봉인된 편지의 차이

먼저 자물쇠 이야기부터 하겠습니다. 인터넷에서 브라우저와 서버가 대화하는 약속을 HTTP라고 부릅니다. Hyper Text Transfer Protocol, 어려워 보이지만 그냥 "웹에서 정보를 주고받는 규칙" 정도로 생각하시면 돼요. 문제는 이 기본 HTTP가 내용을 그대로 노출한 채 보낸다는 겁니다.

비유하자면 HTTP는 엽서예요. 엽서는 봉투가 없죠. 우체통에서 여러분 집에 도착하기까지 여러 우체국과 집배원의 손을 거치는데, 그 사람들이 마음만 먹으면 엽서에 적힌 내용을 다 읽을 수 있습니다. 인터넷도 똑같아요. 여러분의 데이터는 집 공유기, 통신사, 여러 중간 장비를 거쳐 서버에 도착합니다. 그 경로 어딘가에서 누군가 엿보고 있다면, HTTP로 보낸 비밀번호는 그냥 눈앞에 활자로 보입니다.

그래서 나온 게 HTTPS입니다. 끝에 붙은 'S'는 Secure(안전한)의 S예요. HTTPS는 편지를 봉인된 봉투에 넣어 보내는 겁니다. 중간에 누가 봉투를 가로채도, 안에 뭐가 적혔는지는 뜯어볼 수 없어요. 오직 받는 사람(서버)만 열 수 있는 자물쇠로 잠겨 있으니까요. 이 봉인 기술을 암호화(Encryption)라고 부릅니다.

💡 암호화가 뭔가요? 원래 글자를 아무 의미 없는 뒤죽박죽 문자로 바꿔서, 정해진 열쇠가 있는 사람만 원래대로 되돌릴 수 있게 만드는 기술입니다. 예를 들어 "안녕"이라는 글자가 전송 중에는 "8f3a2c…" 같은 암호문으로 바뀌어 흘러가요. 열쇠가 없으면 아무리 들여다봐도 뜻을 알 수 없습니다.

그럼 이 자물쇠와 열쇠를 브라우저와 서버는 어떻게 서로 나눠 갖는 걸까요? 여기서 등장하는 게 SSL 인증서(요즘은 정확히는 TLS 인증서라고 부릅니다)입니다. 이건 "이 사이트가 진짜 그 사이트가 맞다"는 걸 증명하는 신분증 겸 봉인 도구예요. 브라우저는 사이트에 접속할 때 이 인증서를 받아서, "믿을 만한 기관이 발급한 진짜 인증서인지" 확인하고, 확인되면 안전한 봉인 통로를 엽니다. 이 인증서를 실제로 발급받아 내 사이트에 붙이는 방법은 이야기가 길어서 SSL 인증서 설치 이야기에서 따로 자세히 다뤘으니, 궁금하신 분은 그 글을 함께 보세요.

여기서 꼭 짚을 게 하나 있어요. HTTPS 자물쇠가 있다고 해서 "이 사이트는 착한 사이트"라는 뜻은 아닙니다. 자물쇠는 "너와 이 서버 사이의 대화가 도청당하지 않는다"만 보장할 뿐, 그 서버 주인이 사기꾼인지 아닌지는 알려주지 않아요. 요즘은 피싱 사이트도 대부분 자물쇠를 달고 있습니다. 그러니 자물쇠는 필요조건이지 충분조건이 아니라는 것, 이것만 기억해두세요.

제가 초보 때 가장 흔히 했던 착각이 "내 사이트는 작고 아무도 안 볼 텐데 굳이 HTTPS까지 필요할까?"였습니다. 그런데 이건 완전히 거꾸로 된 생각이더군요. 공격은 사람이 일일이 골라서 하는 게 아니라, 인터넷 전체를 자동으로 훑는 프로그램이 합니다. 크든 작든 봉인 안 된 편지를 발견하면 그냥 주워 가는 거예요. 게다가 요즘 브라우저는 HTTPS가 아닌 사이트에 아예 "안전하지 않음" 경고를 띄우기 때문에, 방문자가 첫 화면에서 겁먹고 나가버립니다. 다행히 요즘은 무료로 발급받는 인증서도 잘 갖춰져 있어서, HTTPS를 켜는 비용은 사실상 시간 조금뿐입니다. 안 켤 이유가 없어요.

HTTP는 엽서, HTTPS는 봉인된 편지입니다. 로그인·결제·개인정보가 오가는 곳이라면 반드시 봉인된 편지(HTTPS)여야 합니다. 엽서로 비밀번호를 보내는 건, 붐비는 지하철에서 통장 비밀번호를 큰 소리로 외치는 것과 같아요.

인증 vs 인가 — 이름은 비슷한데 완전히 다른 일

이제 오늘의 핵심입니다. 인증인가. 두 글자 중 한 글자만 다르고 영어로도 둘 다 'Auth'로 시작해서, 개발 좀 하는 사람들도 은근히 헷갈려 합니다. 그런데 개념 자체는 아주 명확해요. 회사 건물에 들어가는 장면으로 비유하면 단번에 정리됩니다.

인증은 건물 1층 로비에서 "당신 누구세요?"를 확인하는 겁니다. 신분증을 보여주고, 얼굴을 대조하고, "네, 이 사람 맞네요" 하고 통과시키는 절차죠. 웹에서는 아이디·비밀번호를 확인하는 로그인이 바로 이 단계입니다. 핵심 질문은 "너 누구니?"예요.

인가는 그다음입니다. 신원이 확인돼서 건물엔 들어왔는데, 그렇다고 아무 방이나 다 들어갈 수 있는 건 아니잖아요. 사장실은 못 들어가고, 서버실은 관리자만 들어가고, 일반 직원은 자기 부서 사무실만. 이렇게 "이 사람이 이 문을 열 권한이 있는가?"를 확인하는 게 인가입니다. 핵심 질문은 "너 그거 해도 되니?"예요.

순서가 중요합니다. 인증이 항상 먼저, 인가가 나중입니다. 누구인지도 모르는데 권한을 따질 수는 없으니까요. 로비에서 신원 확인(인증)을 통과해야, 각 방 앞에서 권한 확인(인가)이 시작됩니다. 표로 깔끔하게 정리해드릴게요.

구분인증 (Authentication)인가 (Authorization)
핵심 질문너 누구니?그건 해도 되니?
확인하는 것신원(내가 나임)권한(할 수 있는 범위)
비유로비에서 신분증 확인각 방 문 앞 출입 권한 확인
웹에서의 예아이디·비밀번호 로그인관리자만 회원 삭제 가능
순서먼저 (1단계)나중 (2단계)
실패했을 때"로그인이 필요합니다""접근 권한이 없습니다"
💡 쉽게 외우는 법 화면에서 "로그인해 주세요"가 뜨면 인증(누군지 모름)에서 막힌 거고, 로그인은 했는데 "권한이 없습니다"가 뜨면 인가(누군진 아는데 이건 못함)에서 막힌 겁니다. 에러 문구만 봐도 어느 단계에서 걸렸는지 알 수 있어요.

제가 초보 때 이걸 왜 헷갈렸냐면, 개인 프로젝트에서는 로그인만 하면 나 혼자 다 쓰니까 인가가 필요 없었거든요. 나 혼자면 "너 누구니"만 있으면 되죠. 그런데 회원이 여럿 생기고, 일반 회원과 관리자를 나누기 시작하면서 비로소 "이 사람은 이건 되고 저건 안 되고"를 나눌 필요가 생겼습니다. 그때 인가라는 개념이 확 와닿았어요. 사람이 여럿 모이는 순간 권한 나누기가 시작되는 겁니다.

출입증의 두 방식 — 세션/쿠키 vs 토큰(JWT)

자, 로그인(인증)에 성공했다고 칩시다. 그런데 여기서 문제가 하나 있어요. 웹이라는 건 원래 지독하게 건망증이 심합니다. 페이지를 한 번 넘길 때마다 서버는 여러분을 처음 보는 사람처럼 대해요. 방금 로그인한 사실을 서버는 다음 순간이면 까먹습니다. 그래서 페이지를 넘길 때마다 비밀번호를 다시 묻지 않으려면, "이 사람 아까 확인 끝났음"을 증명할 출입증이 필요합니다. 이 출입증을 만드는 방식이 크게 두 갈래예요.

방식 1: 세션 + 쿠키 (놀이공원 손목밴드)

첫 번째는 세션(Session) 방식입니다. 놀이공원 입장을 떠올려보세요. 매표소에서 표를 확인하면, 직원이 손목밴드를 하나 채워줍니다. 그리고 매표소 뒤 명부에는 "3번 밴드 = 김부장, 자유이용권"이라고 적어두죠. 이제 여러분은 놀이기구를 탈 때마다 손목밴드만 보여주면 됩니다. 직원은 밴드 번호로 명부를 조회해서 "아, 3번, 자유이용권 손님이네" 하고 통과시켜요.

여기서 손목밴드가 쿠키(Cookie)이고, 매표소 뒤 명부가 세션입니다. 쿠키는 브라우저가 보관하는 작은 쪽지인데, 여기엔 "세션 번호" 같은 열쇠 하나만 들어 있어요. 실제 정보(당신이 누구고 무슨 권한인지)는 전부 서버의 명부에 있습니다. 그래서 손목밴드 자체엔 별 정보가 없고, 잃어버려도 서버가 명부에서 그 번호를 무효 처리하면 그만이에요.

방식 2: 토큰 / JWT (위조 방지 스티커가 붙은 신분증)

두 번째는 토큰(Token) 방식, 그중에서도 요즘 널리 쓰이는 JWT(제이슨 웹 토큰이라고 읽습니다)입니다. 이건 명부에 적어두는 대신, 출입증 자체에 정보를 다 써넣는 방식이에요. 비유하면 위조 방지 홀로그램이 박힌 신분증입니다.

이 신분증에는 "이름: 김부장, 등급: 일반회원, 유효기간: 오늘 밤 12시까지" 같은 정보가 적혀 있고, 그 위에 서버만 찍을 수 있는 특수 도장(전자 서명)이 찍혀 있어요. 그래서 손님이 이 신분증을 내밀면, 직원은 명부를 뒤질 필요 없이 도장이 진짜인지만 확인하면 됩니다. 도장이 진짜면 내용도 진짜인 거죠. 누가 내용을 몰래 고치면 도장이 깨져서 바로 들통납니다.

💡 꼭 짚고 갈 점 JWT는 서명으로 "위조 방지"는 되지만, 내용 자체는 누구나 열어볼 수 있게 들어 있는 경우가 많습니다(암호화가 아니라 서명이에요). 그러니 토큰 안에 비밀번호나 주민번호 같은 민감 정보를 절대 넣으면 안 됩니다. 신분증 겉면에 통장 비밀번호를 적어두는 꼴이 되니까요.

두 방식은 각자 장단점이 뚜렷합니다. 어느 하나가 무조건 좋은 게 아니에요. 상황에 맞게 고르는 거죠.

👍 세션/쿠키가 편할 때

  • 서버가 명부를 쥐고 있어 강제 로그아웃이 쉬움(밴드 번호 무효 처리)
  • 브라우저 하나로 쓰는 일반 웹사이트에 자연스럽게 맞음
  • 출입증에 정보가 없어 노출돼도 피해가 작음

👎 토큰(JWT)이 편할 때

  • 서버가 명부를 안 뒤져도 되니 서버 여러 대로 확장하기 좋음
  • 앱·웹·외부 서비스 등 여러 클라이언트가 붙을 때 유리
  • 대신 한번 발급하면 만료 전 강제 회수가 까다로움

표로도 나란히 정리해드릴게요.

비교 항목세션 + 쿠키토큰 (JWT)
비유손목밴드 + 명부도장 찍힌 신분증
정보 위치서버(명부)출입증 자체
서버 부담명부 보관·조회 필요서명 검증만
강제 로그아웃쉬움상대적으로 까다로움
확장·다양한 기기상대적으로 번거로움유리함

여기서 한 가지 오해를 풀어드릴게요. 세션이든 토큰이든, 이 출입증이 도둑맞으면 상대는 비밀번호를 몰라도 나인 척할 수 있습니다. 그래서 출입증에는 반드시 만료 시간을 둡니다. 놀이공원 손목밴드가 그날 밤이면 못 쓰게 되는 것처럼요. 특히 토큰 방식에서는 "짧게 사는 출입증(액세스 토큰)"과 "그걸 조용히 갱신해주는 열쇠(리프레시 토큰)"를 나눠 쓰는 방식이 흔합니다. 출입증은 자주 새로 갈아 도둑맞아도 금방 무용지물이 되게 하고, 갱신 열쇠는 더 안전한 곳에 깊이 숨겨두는 거예요. 이름이 복잡해 보여도, "출입증은 오래 못 쓰게, 갱신은 따로" 이 한 줄이 전부입니다.

초보자에게 드리는 솔직한 조언은 이겁니다. 처음엔 어느 쪽이든 프레임워크가 시키는 기본값을 그대로 쓰세요. 요즘 도구들은 세션이든 토큰이든 안전한 기본 설정을 제공합니다. "세션이냐 토큰이냐"를 놓고 고민하다 정작 더 중요한 걸(HTTPS, 비밀번호 저장) 놓치는 게 초보의 흔한 함정이에요. 개념만 구분할 줄 알면, 선택은 나중에 필요할 때 해도 늦지 않습니다.

비밀번호는 어떻게 저장하나 — 절대 평문 금지

이제 아주 중요한 이야기입니다. 여러분이 회원가입할 때 정한 비밀번호를, 서버는 어떻게 보관하고 있을까요? 초보들이 가장 크게 오해하는 지점이 여기예요. "당연히 데이터베이스에 그대로 저장해두고, 로그인할 때 입력값이랑 비교하는 거 아니야?"라고요. 절대 그러면 안 됩니다.

비밀번호를 입력한 그대로(이걸 평문이라고 합니다) 저장하는 건, 아파트 관리사무소가 모든 세대의 현관 비밀번호를 공책에 적어 서랍에 넣어두는 것과 같아요. 관리사무소가 한 번만 털리면 모든 집이 동시에 뚫립니다. 더 무서운 건, 사람들이 여러 사이트에서 같은 비밀번호를 돌려쓰기 때문에, 한 사이트가 털리면 그 사람의 다른 사이트까지 줄줄이 뚫린다는 점이에요.

그래서 제대로 만든 서비스는 비밀번호를 해시(Hash)라는 방식으로 저장합니다. 해시는 원래 값을 되돌릴 수 없는 지문으로 바꾸는 겁니다. "사과"를 해시하면 "a1b2c3…" 같은 고정 길이의 문자열이 나오는데, 이 지문에서 "사과"를 거꾸로 알아낼 방법이 없어요. 대신 같은 입력은 항상 같은 지문을 만들죠.

그럼 로그인은 어떻게 확인할까요? 여러분이 입력한 비밀번호를 그 자리에서 해시해서, 저장된 지문과 지문끼리만 비교합니다. 원래 비밀번호는 서버 어디에도 저장돼 있지 않아요. 서버조차 여러분의 진짜 비밀번호를 모르는 겁니다. 이게 정상이에요. 그래서 요즘 서비스들이 "비밀번호를 잊으셨나요?"에서 원래 비밀번호를 알려주지 못하고 재설정만 시키는 거예요. 원래 값을 자기들도 모르니까요. 만약 어떤 사이트가 가입한 비밀번호를 그대로 이메일로 다시 보내준다면, 그 사이트는 평문으로 저장하고 있다는 위험 신호입니다.

여기에 하나 더 얹는 게 솔트(Salt)입니다. 소금이라는 뜻인데, 해시하기 전에 사람마다 다른 무작위 문자열을 살짝 뿌려주는 거예요. 왜 필요하냐면, 솔트가 없으면 "1234"나 "password" 같은 흔한 비밀번호는 항상 같은 지문이 나오거든요. 공격자는 흔한 비밀번호의 지문 목록(무지개 표라고 부릅니다)을 미리 만들어두고 대조만 하면 됩니다. 그런데 사람마다 다른 소금을 뿌리면, 똑같이 "1234"를 써도 지문이 전부 달라져서 그 미리 만든 목록이 무용지물이 돼요.

🔑 비밀번호 저장의 3원칙 ①평문으로 저장하지 않는다. ②해시로 지문만 저장한다. ③사람마다 다른 솔트를 뿌린다. 그리고 실무에서는 이걸 직접 구현하지 말고 검증된 라이브러리(bcrypt, argon2 등)를 쓰세요. 이런 도구들은 해시+솔트에 더해 "일부러 느리게 계산하기"까지 넣어서, 공격자가 무차별 대입을 못 하게 막아줍니다. 직접 만든 암호 코드가 가장 위험합니다.

2단계 인증(2FA)과 소셜 로그인(OAuth)

비밀번호 하나만으로는 불안합니다. 남이 알아내면 끝이니까요. 그래서 나온 게 2단계 인증(2FA)입니다. 이름 그대로 신원 확인을 두 번 하는 거예요. "아는 것(비밀번호)"에 더해 "가진 것(내 휴대폰)"을 하나 더 확인합니다. 비밀번호를 맞게 넣어도, 내 폰으로 온 6자리 인증번호나 인증 앱의 숫자를 추가로 넣어야 통과되죠. 비유하면 현관 도어록에 더해 열쇠까지 있어야 문이 열리는 이중 잠금입니다. 도둑이 비밀번호를 훔쳐봤어도 내 폰이 없으면 못 들어와요. 조금 번거롭지만, 중요한 계정(이메일, 금융, 개발 서버)에는 반드시 켜두시길 권합니다. 보안에서 가장 가성비 좋은 한 수예요.

또 하나, 요즘 흔한 "구글로 로그인" "카카오로 로그인" 버튼. 이건 소셜 로그인이고, 뒤에서 도는 기술이 OAuth(오오쓰라고 읽어요)입니다. 원리는 호텔 발렛파킹과 비슷해요. 발렛 직원에게 차 전체 열쇠가 아니라 발렛용 열쇠만 주잖아요. 트렁크는 못 열고 운전만 되는 제한된 열쇠요. OAuth도 마찬가지입니다. 새 사이트에 내 구글 비밀번호를 알려주는 게 아니라, 구글이 "이 사람 신원은 우리가 보증할게, 대신 이메일 주소 정도만 알려줄게" 하고 제한된 허가증만 발급해줍니다. 덕분에 사이트마다 비밀번호를 새로 만들 필요가 없고, 그 사이트가 털려도 내 구글 비밀번호는 안전하죠. 다만 그 구글·카카오 계정 하나가 뚫리면 연결된 게 다 위험해지니, 소셜 로그인의 원 계정일수록 2FA를 꼭 켜야 합니다.

흔한 위협 3가지와 방어법

이제 나쁜 사람들이 실제로 어떻게 공격하는지, 그리고 우리가 어떻게 막는지를 쉬운 것 위주로 세 가지만 보겠습니다. 적을 알아야 방어가 되니까요.

1

피싱 (가짜 낚시터)

진짜와 똑같이 생긴 가짜 로그인 페이지로 유도해서 비밀번호를 낚아채는 수법입니다. "계정이 정지됐으니 확인하세요" 같은 급한 문자·메일로 링크를 누르게 하죠. 방어: 링크를 바로 누르지 말고 주소창의 도메인을 직접 확인하세요. 은행 앱은 검색이 아니라 즐겨찾기·공식 앱으로 들어가고, 2FA를 켜두면 비밀번호가 새어도 한 겹 더 막힙니다.

2

세션 탈취 (손목밴드 도둑)

여러분의 출입증(세션 쿠키·토큰)을 중간에서 훔쳐, 비밀번호 없이도 로그인된 척하는 공격입니다. 방어: 우선 HTTPS가 필수예요(엽서로 밴드를 보내면 훔치기 쉬우니까). 그리고 쿠키에 안전 옵션(자바스크립트로 못 읽게, HTTPS에서만 전송)을 켜고, 출입증에 만료 시간을 둬서 훔쳐도 오래 못 쓰게 합니다. 공용 PC에서는 꼭 로그아웃하세요.

3

약한 비밀번호 / 무차별 대입

"1234"나 흔한 단어를 컴퓨터가 초당 수없이 대입해 뚫는 공격입니다. 방어: 길고 남들이 안 쓰는 비밀번호를 쓰고, 사이트마다 다르게 쓰세요(비밀번호 관리자 앱을 추천합니다). 서버 쪽에서는 로그인 실패가 여러 번이면 잠깐 막고(속도 제한), 해시를 일부러 느리게 계산해 대입 자체를 비싸게 만듭니다.

보안의 기본 태도는 이겁니다. "한 겹이 뚫려도 다음 겹이 막아준다." 완벽한 벽 하나가 아니라, 여러 겹의 방어를 겹쳐 쌓는 것. HTTPS, 강한 비밀번호, 해시 저장, 2FA — 각각은 완벽하지 않아도, 겹치면 뚫기가 훨씬 어려워집니다.

개인정보와 최소 권한의 원칙

보안에서 기술만큼 중요한 게 태도입니다. 그중 가장 중요한 두 가지 원칙을 말씀드릴게요.

첫째, 안 받으면 안 샌다. 개인정보는 모을수록 자산이 아니라 부채에 가깝습니다. 이름·전화번호·주소를 잔뜩 모아두면, 그게 다 털렸을 때 물어줄 빚이 됩니다. 그러니 서비스에 꼭 필요한 정보만 최소한으로 받으세요. 생일 이벤트를 안 할 거면 생년월일을 받지 마세요. 안 가진 데이터는 절대 유출되지 않습니다. 이게 가장 확실한 개인정보 보호예요.

둘째, 최소 권한의 원칙입니다. 이건 인가와도 이어져요. 모든 사람과 프로그램에게 "그 일에 딱 필요한 만큼의 권한만" 주라는 원칙입니다. 청소하는 분에게 금고 열쇠까지 줄 필요는 없잖아요. 청소에 필요한 방 열쇠만 드리면 됩니다. 프로그램도 마찬가지예요. 게시글만 읽는 기능에 회원 삭제 권한까지 딸려 있으면, 그 기능이 악용될 때 피해가 걷잡을 수 없이 커집니다.

이 원칙은 코드뿐 아니라 비밀 값 관리에서도 똑같이 적용됩니다. API 키나 데이터베이스 비밀번호 같은 걸 코드에 그대로 박아두면, 그 코드가 공개되는 순간 다 털려요. 이런 비밀 값을 코드와 분리해 안전하게 다루는 방법은 환경변수와 비밀 값 관리 이야기에서 따로 정리해두었으니 꼭 함께 읽어보세요. 그리고 요즘은 AI에게 코드를 맡기는 일이 많은데, AI에게 민감한 정보를 어디까지 보여줘도 되는지도 조심해야 합니다. 이 부분은 AI를 쓸 때 조심할 점에서 다뤘어요.

초보가 흔히 하는 실수 & 해결

제가 직접 저질렀거나, 주변 입문자들이 자주 밟는 지뢰를 모았습니다. 하나라도 해당된다면 오늘 바로 고치세요.

👎 이런 실수, 꼭 피하세요

  • 비밀번호를 데이터베이스에 평문으로 저장
  • 로그인 페이지를 HTTP(엽서)로 열어둠
  • JWT 토큰 안에 민감 정보를 담아둠
  • API 키·비밀번호를 코드에 그대로 박아 공개 저장소에 올림
  • 모든 회원에게 관리자 권한을 줘버림(인가 미분리)
  • 암호화 코드를 직접 만들어

👍 이렇게 하세요

  • 해시+솔트로 지문만 저장(검증된 라이브러리 사용)
  • 사이트 전체를 HTTPS로(무료 인증서로도 충분)
  • 토큰엔 식별자·권한 등급 정도만 담기
  • 비밀 값은 환경변수로 분리, 저장소엔 절대 안 올림
  • 일반/관리자 역할을 나눠 권한 확인(인가) 넣기
  • 보안 기능은 검증된 라이브러리·프레임워크에 맡기기

특히 네 번째, API 키를 코드에 박아 공개 저장소에 올리는 실수는 정말 흔합니다. 저도 초보 때 무심코 올렸다가 식은땀 흘린 적 있어요. 공개 저장소는 전 세계가 보는 곳이고, 자동으로 키를 긁어가는 프로그램까지 돌아다닙니다. 올린 지 몇 분 만에 도용될 수 있어요. 한번 올라간 키는 삭제해도 기록에 남으니, 반드시 즉시 폐기하고 새로 발급받아야 합니다.

자주 묻는 질문 (FAQ)

Q. HTTPS만 쓰면 우리 사이트는 안전한 건가요?
A. 아니요. HTTPS는 "오가는 내용의 도청·변조"만 막습니다. 비밀번호를 평문으로 저장하거나, 권한 확인(인가)을 안 하거나, 약한 비밀번호를 방치하면 여전히 위험해요. HTTPS는 여러 겹 방어 중 기본 한 겹일 뿐입니다.

Q. 인증과 인가, 실무에서 정말 자주 헷갈리나요?
A. 네, 많이 헷갈립니다. 팁을 다시 드리면, 화면에 "로그인해 주세요"가 뜨면 인증 문제, "권한이 없습니다"가 뜨면 인가 문제예요. 이 문구 구분법만 알아도 실무 대화가 훨씬 편해집니다.

Q. 세션이랑 토큰(JWT), 초보는 뭘 쓰는 게 좋아요?
A. 처음엔 쓰시는 프레임워크의 기본값을 그대로 따르세요. 대부분 안전한 설정을 제공합니다. 개념 차이(명부에 두느냐, 출입증에 담느냐)만 이해하고, 선택은 서비스가 커져서 실제로 고민이 생길 때 해도 늦지 않아요.

Q. 비밀번호를 해시로 저장하면, 사용자가 잊었을 때 못 알려주잖아요?
A. 맞습니다. 그리고 그게 정상이에요. 원래 값을 서버도 몰라야 안전하니까요. 그래서 "원래 비밀번호 찾기"가 아니라 "새 비밀번호로 재설정"을 시키는 겁니다. 원래 비밀번호를 그대로 알려주는 사이트가 오히려 위험 신호예요.

Q. 2단계 인증(2FA)은 너무 번거로운데 꼭 해야 하나요?
A. 모든 계정에 강요할 필요는 없지만, 이메일·금융·개발 계정처럼 뚫리면 피해가 큰 곳은 반드시 켜세요. 로그인마다 몇 초 더 쓰는 대신, 비밀번호가 새어도 한 겹 더 막아줍니다. 보안 대비 편의 손해가 가장 적은, 가성비 최고의 조치입니다.

마무리 체크리스트

오늘 이야기는 딱 세 질문으로 요약됩니다. 편지를 봉인했는가(HTTPS), 너 누구니(인증), 그건 해도 되니(인가). 이 셋만 구분해도 여러분은 이미 웹 보안의 큰 지도를 손에 쥔 겁니다. 마지막으로 실천용 체크리스트를 드릴게요. 내 서비스나 자주 쓰는 계정에 하나씩 대입해보세요.

보안은 한 번에 완성하는 게 아니라, 한 겹 한 겹 쌓아가는 겁니다. 오늘 이 글에서 딱 한 가지만 실천하신다면, 자주 쓰는 이메일 계정에 2단계 인증부터 켜보세요. 5분이면 되고, 효과는 확실합니다. 완벽하지 않아도 괜찮아요. 한 겹씩 쌓다 보면 어느새 꽤 튼튼한 문을 갖게 되실 겁니다. 저도 그렇게 하나씩 배웠으니까요.

다음 글에서는 이 이야기와 짝이 되는 비밀 값(환경변수) 관리를 더 깊이 들여다볼 예정입니다. 자물쇠는 달았는데 열쇠를 문 앞에 놔두면 소용없으니까요. 그럼 다음에 또 뵙겠습니다. 겁먹지 말고, 천천히 같이 가요.

(2026년 8월 기준 작성 — 화면·정책·도구는 바뀔 수 있으니 공식 문서를 함께 확인하세요.)

「코딩 몰라도 AI로 사주앱 만들기」기획부터 AWS 배포·도메인 연결까지 손잡고 가는 237쪽 실전 가이드
교보 → YES24 →
← 기술 블로그 목록으로