Claude Code와 함께한 워드프레스에서 Hugo로의 블로그 마이그레이션

더 이상 참을 수 없었던 셀프호스팅 워드프레스의 한계 셀프 호스팅 워드프레스를 버전 업데이트 없이 너무 오래 방치했더니 나도 모르게 취약점에 의해 악의적인 코드가 주입되어 간헐적으로 이상한 웹사이트로 리디렉션된다는 사실을 최근에 파악했다. 처음에는 악성 크롬 익스텐션이나 다른 스크립트 문제인 줄 알았는데, 알고보니 워드프레스 자체에 악성 코드가 삽입되어 있었던 것이다. 공식 플러그인 중 하나인 akismet의 파일 중 하나에 이런 코드가 심어져있었다. 어떤 취약점을 통해 이렇게 된 것인지 까지는 파악 실패했으나 얼핏 봐도 수상하길래 ChatGPT에 물어보니 공격자가 나중에 POST로 원하는 명령을 보내서 동적으로 코드 실행이 가능한 백도어라고 한다. ...

2025년 7월 14일 · 8분 · 1650단어

자바스크립트로 크롤러 만들기 4편: 실제 웹페이지 크롤링해보기

1,2,3편에서 배운 지식들을 이용하여 이번편에서는 실제 웹사이트를 크롤링해서 데이터를 추출하는 것을 실습할 차례입니다. 드디어 마지막 편입니다. 조금만 힘내서 자바스크립트로 크롤링하는 기술을 마스터 해봅시다! 크롤링할 사이트 소개 코로나보드의 데이터는 질병관리청에서 운영하는 코로나19 웹사이트로부터 크롤링을 합니다. 이렇게 실제 웹페이지에 맞춰서 크롤러를 만들어 두면 만든 직후에는 잘 동작하지만, 해당 사이트의 구성이나 디자인이 업데이트되는 순간 웹페이지 내의 데이터 위치도 같이 바뀌기 때문에 기존 크롤러 코드가 제대로 동작을 하지 않을 가능성이 큽니다. 때문에 크롤러의 코드는 지속적인 유지보수가 필요합니다. 이 책에서는 이러한 유지보수를 피하고 설명의 일관성을 유지하고자 실제 크롤링할 웹페이지 전체를 클론해서 학습용으로 제공합니다 . ...

2022년 5월 9일 · 7분 · 1467단어

자바스크립트로 크롤러 만들기 3편: 다양한 유형의 웹페이지 크롤러 만들어보기

자바스크립트 크롤러 만들기 튜토리얼 1편, 2편에서는 크롬 웹 브라우저에서 제공하는 [개발자 도구]를 이용하여 이미 열려 있는 웹페이지에서 원하는 정보를 찾는 방법을 알아보았습니다. 그런데 이 방식은 웹 브라우저를 실행한 후 사용자가 웹페이지를 직접 열고 [개발자 도구]에서 자바스크립트 코드를 입력해야 하므로 자동화가 쉽지 않습니다. (참고: ‘헤드리스 브라우저를 이용한 크롤링’에서 헤드리스headless 브라우저를 이용하여 UI 없는 웹 브라우저를 코드만으로 조작하는 방식으로 크롤링이 가능하긴 합니다) 웹 브라우저와 독립적으로 동작하는 CLIcommand line interface 기반 크롤러를 만들면 이 문제를 해결할 수 있습니다. CLI 애플리케이션으로 만들면 터미널terminal 또는 셸shell에서 쉽게 테스트해볼 수 있고, 서버에서 주기적으로 자동 실행되게 만들 수도 있습니다. ...

2022년 5월 9일 · 16분 · 3340단어

자바스크립트로 크롤러 만들기 2편: 웹페이지 크롤링을 위한 배경 지식 알아보기

웹 크롤링을 하려면 웹페이지 구조인 DOM과 CSS 셀렉터 문법을 알아야 합니다. 각각을 알아봅시다. 웹페이지와 DOM 웹페이지는 HTML 형식으로 제공되는 일종의 문서라고 생각할 수 있습니다. 웹 브라우저로 웹페이지에 접근한다는 것은, 간단히 말해 서버로부터 해당 주소에서 제공하는 HTML 문서를 HTTP 통신으로 전달받는 것을 의미합니다. 전달받은 HTML 문서는 단순 텍스트 형태이기 때문에 프로그램에서 사용하기 좋은 데이터 구조로 표현해야 하는데, 이 구조를 DOM이라고 부릅니다. DOMDocument Object Model은 최상위 노드node와 여러 단계의 자식 노드들로 구성된 트리tree 구조입니다. 따라서 원하는 노드를 쉽게 찾아서 수정/삭제하거나 원하는 위치에 새로운 노드를 추가할 수 있습니다. ...

2022년 5월 9일 · 8분 · 1502단어

자바스크립트로 크롤러 만들기 1편: 크롤링을 위한 크롬 개발자 도구 사용법 익히기

크롤링을 하기 전에 대상 웹페이지의 구조를 파악하고 원하는 정보만 효율적으로 추출해올 방법을 구상해야 합니다. 웹페이지 구조를 분석하는 가장 좋은 방법은 웹 브라우저에 내장된 [개발자 도구]를 이용하는 겁니다. [개발자 도구]에서는 현재 웹페이지의 HTML 구조를 라이브로 볼 수 있고, HTML 요소에 적용된 CSS 스타일을 조사한다거나, 웹페이지에서 수행되는 HTTP 요청/응답 내용을 모니터링하거나, 자바스크립트 코드를 디버깅하는 등 매우 다양한 일을 할 수 있습니다. 이러한 기능들은 크롤링할 웹페이지를 파악하는 데도 매우 유용하지만 자신이 개발 중인 웹페이지를 디버깅하는 데도 거의 필수로 쓰이니 사용법을 잘 익혀두면 많은 도움이 됩니다. 이번 장뿐만 아니라 나중에 프런트엔드 개발을 진행할 때도 [개발자 도구]를 계속 사용할 것이라서 일반적으로 자주 사용되는 기능을 하나하나 설명하겠습니다. ...

2022년 5월 9일 · 7분 · 1286단어

자바스크립트로 크롤러 만들기: 크롤링 개념 및 튜토리얼 소개

본 튜토리얼 시리즈에서는 필자가 개발하고 운영했던 코로나19 통계 정보 제공 사이트인 코로나보드에 실제 사용되었던 코드 기반으로 자바스크립트 크롤러를 만드는 방법에 대해서 설명합니다. 본 글의 내용은 필자가 집필한 ‘코로나보드로 배우는 실전 웹 서비스 개발’ 책의 일부를 발췌해서 튜토리얼 형식에 맞게 재구성하였습니다. 글은 지금 보고계신 소개글 외에 총 4편으로 구성되어있습니다. 자바스크립트로 크롤러 만들기 소개: 크롤링 개념 및 튜토리얼 소개 자바스크립트로 크롤러 만들기 1편: 크롤링을 위한 크롬 개발자 도구 사용법 익히기 자바스크립트로 크롤러 만들기 2편: 웹페이지 크롤링을 위한 배경 지식 알아보기 자바스크립트로 크롤러 만들기 3편: 다양한 유형의 웹페이지 크롤러 만들어보기 자바스크립트로 크롤러 만들기 4편: 실제 웹페이지 크롤링해보기 그럼 이제 본격적으로 크롤러를 개발하기 전에 개념적인 부분들 부터 소개해보도록 하겠습니다. ...

2022년 5월 9일 · 3분 · 479단어

API 서버 인증을 위한 JWT와 JWK 이해하기

쿠키(cookie)를 이용한 세션기반의 인증의 경우 특정 웹서버에서 세션 상태(session state)를 유지해야 하기 때문에 stateless 하지않다. 서버 로직이 Stateless가 아닌 경우 더 많은 요청을 처리하기 위해 동일한 서버의 숫자를 늘리는 스케일 아웃(scale out)에 적합하지 않다. 또한 도메인이 다른 서버에 대해서는 해당 세션 쿠키가 공유되지 않기 때문에 도메인이 다른 서버에 요청하기 위해서는 매번 새롭게 인증을 해야하는 불편함도 존재한다. 이 문제를 해결하기 위해 매번 http 요청마다 http header에 인증 토큰(authorization token)을 같이 보내는 형태의 방법을 많이 사용한다. 일반적으로 토큰 안에는 어떤 유저가 보내는 요청인지 구분하기 위해서 유저 ID값이 포함된다. 이 방법을 사용하면 서버쪽에서 세션 상태를 유지할 필요가 없어서 스케일 아웃에 적합하며, 도메인이 다른 서버에 요청하는 경우에도 동일한 토큰을 그대로 사용할 수 있다. 이러한 토큰기반의 인증을 적용하는 경우 악의적인 유저가 다른 유저ID를 사칭하는 것을 방지하기 위해서 토큰에 서명(signature)을 포함하거나, 대칭키 암호화를 적용한다. ...

2018년 10월 28일 · 5분 · 980단어

인증서 파일 형식 및 확장자의 차이점 비교 설명 (Certificate file format & extensions)

https를 지원하는 웹서버를 설정하거나 서명이나 암호화 관련된 개발을 하게되면 한번씩 인증서 관련된 파일을 다룰 일이 생기게 된다. 이때 항상 프로그램이나 라이브러리들이 지원하는 형식이 달라서 인증서 형식을 변환해아 하는데 현재 갖고있는 파일의 형식이 무엇인지를 알아야 제대로 활용이 가능하다. 인증서 파일의 경우 인코딩 방식과 확장자가 일치하는 경우도 있고, 그렇지 않은 경우도 있기 때문에 아래와 같이 비교해서 정리해 보았다. 인코딩 (확장자로 쓰이기도 한다.) .der: Distinguished Encoding Representation (DER) 바이너리 DER 형식으로 인코딩된 인증서. 텍스트 편집기에서 열었는데 읽어들일 수 없다면 이 인코딩일 확률이 높다. .pem: X.509 v3 파일의 한 형태 PEM (Privacy Enhanced Mail)은 Base64인코딩된 ASCII text file이다. 원래는 secure email에 사용되는 인코딩 포멧이었는데 더이상 email쪽에서는 잘 쓰이지 않고 인증서 또는 키값을 저장하는데 많이 사용된다. -----BEGIN XXX-----, -----END XXX----- 로 묶여있는 text file을 보면 이 형식으로 인코딩 되어있다고 생각하면 된다. (담고있는 내용이 무엇인지에 따라 XXX 위치에 CERTIFICATE, RSA PRIVATE KEY 등의 키워드가 들어있다) 인증서(Certificate = public key), 비밀키(private key), 인증서 발급 요청을 위해 생성하는 CSR (certificate signing request) 등을 저장하는데 사용된다. 확장자 .crt, .cer 인증서를 나타내는 확장자인 cer과 crt는 거의 동일하다고 생각하면 된다. (cer은 Microsoft 제품군에서 많이 사용되고, crt는 unix, linux 계열에서 많이 사용된다.) 확장자인 cer이나 crt만 가지고는 파일을 열어보기 전에 인코딩이 어떻게되어있는지 판단하긴 힘들다. .key: 개인 또는 공개 PKCS#8 키를 의미 .p12: PKCS#12 형식으로 하나 또는 그이상의 certificate(public)과 그에 대응하는 private key를 포함하고 있는 key store 파일이며 패스워드로 암호화 되어있다. 열어서 내용을 확인하려면 패스워드가 필요하다. .pfx: PKCS#12는 Microsoft의 PFX파일을 계승하여 만들어진 포멧이라 pfx와 p12를 구분없이 동일하게 사용하기도 한다. 표준 비교 PKCS#8, PKCS #12, X.509 PKCS #8은 Public-Key Cryptography Standards (PKCS) 표준 중의 일부로 private key를 저장하는 문법에 관한 표준이다. PKCS #8 private keys 는 일반적으로 PEM 형식으로 인코딩된다. ...

2018년 10월 19일 · 5분 · 972단어

크롬 익스텐션 개발 + 리액트 적용하기

크롬 익스텐션(Chrome Extension)은 모두 자바스크립트(Javascript)로 되어있기때문에 웹개발을 해본 사람이라면 그리 큰 노력을 들이지 않고도 개발을 시작 할 수 있다. 하지만 구글에서 익스텐션을 통한 보안이슈가 생기는 것을 막기 위해 다양한 방식으로 익스텐션의 자바스크립트가 실행되는 컨텍스트(context)들을 세분화 시켜두었기 때문에, 이러한 세분화된 컨텍스트에서 각각 어떤 작업이 수행가능한지, 어떻게 분리된 스크립트 컨텍스트간에 통신을 할 수 있는지를 이해하는 것이 생각보다 어렵다. 따라서 본 글에서는 이 부분의 개념에 대해서 자세히 비교 설명하고, 각각의 스크립트들이 잘 동작하도록 미리 설정된 보일러 플레이트 프로젝트를 소개할 예정이다. 대신 크롬 익스텐션에서 사용하는 세부적인 API들이나 manifest관련 세부 설정들은 구글에서 제공하는 문서에도 잘 나와있고, 다양한 sample project에도 케이스별로 잘 나와있기 때문에 따로 정리하지는 않을 예정이다. ...

2018년 7월 21일 · 5분 · 928단어

레디스 클러스터, 센티넬 구성 및 동작 방식

RDBMS만큼의 정합성과 영속성을 보장할 필요가 없는 데이터들을 빠르게 처리하거나 일정 기간동안만 보관하고 있기 위한 용도로 레디스(Redis), memcached 등의 in-memory 기반 저장소가 많이 사용된다. 그중에서도 Redis는 빠른 성능을 유지하면서도 일정 수준 이상의 persistence를 제공하고, 다양한 native 데이터 구조들을 제공하여 효율적이고 편리한 사용이 가능하게 해주기 때문에 다양한 use-case들이 존재한다. 이 글은 실제 명령어를 날려서 레디스를 직접 사용해보는 것을 배우기 보다는 어떤 in-memory 저장소를 선택할지 고민하는 분들을 위해서 주요 운영 방식, 레디스의 내부 동작 방식 및 특징, 주요 클라이언트들에 대한 정보를 제공하는 쪽에 초점이 맞춰져 있다. ...

2018년 6월 19일 · 7분 · 1486단어