923 posts
Playwright로 E2E 테스트 시작하기

Playwright로 E2E 테스트 시작하기

웹 애플리케이션을 개발하다 보면 "이거 진짜 브라우저에서도 잘 되나?" 하는 불안감이 들 때가 있죠. 단위 테스트로 함수 하나하나는 검증했지만, 사용자가 실제로 버튼을 클릭하고 페이지를 이동하고 폼을 제출하는 흐름까지 테스트하려면 별도의 도구가 필요합니다. 이런 종단간(End-to-End) 테스트를 위해 등장한 것이 바로 Playwright입니다. 이 글에서는 Playwright가 무엇인지 살펴보고, 설치부터 테스트 작성과 실행, 그리고 디버깅까지 E2E 테스트의 전체 흐름을 다뤄보겠습니다. Playwright란? Playwrigh

Kotlin에서 JDBC API 사용하기

Kotlin에서 JDBC API 사용하기

JDBC(Java Database Connectivity)는 JVM 위에서 돌아가는 애플리케이션이 데이터베이스와 상호작용하는 데 근간이 되는 API입니다. 이번 포스팅에서는 간단한 예제를 통해서 Kotlin에서 JDBC API를 어떻게 사용하는지에 대해서 살펴보도록 하겠습니다. JDBC API 패키지 JDBC API는 java.sql과 javax.sql, 이렇게 두 개의 패키지로 구성되어 있는데요. java.sql 패키지는 데이터베이스 연결, SQL 쿼리 실행, 결과 집합 처리에 필요한 클래스와 인터페이스를 제공합니다. 본 포스팅에

OAuth Dynamic Client Registration 제대로 이해하기

OAuth Dynamic Client Registration 제대로 이해하기

OAuth 연동을 만들 때 보통 가장 먼저 하는 일은 인가 서버(Authorization Server, 이하 AS)에 애플리케이션을 등록하는 것입니다. 관리 콘솔에 들어가 앱 이름, 리다이렉트 URI, 로고, 권한 범위를 입력하고 client_id와 client_secret을 발급받죠. 구글이나 GitHub처럼 정해진 제공자 한두 곳만 상대한다면 이 방식으로 충분합니다. 그런데 클라이언트와 AS가 미리 서로를 알 수 없는 환경이라면 이야기가 달라집니다. 사용자가 처음 보는 MCP 서버에 AI 클라이언트를 붙이거나, 여러 테넌트가 각

디스코드 봇 만들기: 앱과 봇 개념부터 서버 초대까지

디스코드 봇 만들기: 앱과 봇 개념부터 서버 초대까지

디스코드를 쓰다 보면 "이런 거 자동으로 처리해 주는 봇이 있으면 좋겠다" 싶은 순간이 한 번쯤은 있으셨을 텐데요. 출석 체크, 명령어 한 줄로 정보 조회, 새 멤버 환영 인사처럼 반복적인 일을 봇에게 맡기면 커뮤니티 운영이 한결 수월해집니다. 그런데 막상 봇을 만들려고 하면 "App인지 Bot인지", "토큰은 어디서 받는지"부터 헷갈려서 개발자 포털 화면 앞에서 멈칫하게 되는데요. 그래서 이번 글에서는 꼭 필요한 개념부터 차근차근 잡고, 개발자 포털에서 앱을 만들어 봇 토큰을 발급받아 내 서버에 초대한 뒤, discord.js로

OKLCH: 인간 친화적인 CSS의 색상 모델

OKLCH: 인간 친화적인 CSS의 색상 모델

색상 모델(color space)은 웹 디자인에서 아주 중요한 역할을 합니다. CSS에서는 기존에 RGB나 HSL 모델이 주로 사용되었지만, 최근에는 새로운 색상 모델인 OKLCH가 도입되어 점점 많은 프로젝트에서 채택되고 있습니다. 이번 포스팅에서는 OKLCH이 기존 색상 모델과 어떻게 다른지 알아보고, 간단한 실습을 통해서 OKLCH의 특장점을 살펴보겠습니다. OKLCH 색상 모델이란? 색상 모델(color model)이란 색상을 나타내기 위해서 사용되는 모델 또는 시스템을 뜻합니다. 아주 옛날부터 많이 사용되었던 색상 모델인

Rover CLI로 GraphQL 스키마 관리하기

Rover CLI로 GraphQL 스키마 관리하기

GraphQL을 사용하다 보면 스키마를 관리하는 일이 점점 중요해지는데요. 팀원이 늘어나고 서비스가 커지면서 "이 필드 바꿔도 기존 클라이언트에 문제 없을까?", "지금 운영 중인 스키마가 정확히 뭐였지?" 같은 고민이 생기기 마련이잖아요? 😅 이럴 때 큰 도움이 되는 도구가 바로 Apollo에서 만든 Rover CLI입니다. 이번 글에서는 Rover CLI의 설치부터 주요 명령어, CI/CD 파이프라인 연동까지 쭉 다뤄보겠습니다. Rover CLI란? Rover는 Apollo GraphQL에서 제공하는 공식 CLI 도구입니다.

내 오픈소스에 보안 취약점이 제보되면? GitHub 보안 권고문 대응 가이드

내 오픈소스에 보안 취약점이 제보되면? GitHub 보안 권고문 대응 가이드

오픈소스를 운영하다 보면 스타가 늘거나 이슈가 쌓이는 일에는 어느새 익숙해지는데요. 그러던 어느 날 저장소 Security and quality 탭에 처음 보는 빨간 알림이 뜨고 "당신의 패키지에서 보안 취약점을 발견했습니다"라는 제보가 들어오면 이야기가 달라집니다. 머릿속이 하얗게 변하면서 "이걸 이슈로 답해야 하나? 일단 코드부터 고쳐서 푸시할까?" 하는 생각이 먼저 떠오르죠. 😅 이건 결코 남의 일이 아닌데요. 2021년 전 세계 서버를 떨게 한 Log4j의 Log4Shell 같은 대형 사건도 있었지만, 멀리 갈 것도 없이

GitHub Actions로 빌드 후 GitHub Pages에 배포하기

GitHub Actions로 빌드 후 GitHub Pages에 배포하기

지난 포스팅에서는 저장소의 특정 브랜치를 배포 디렉토리로 지정하여 아주 쉽고 빠르게 GitHub Pages로 웹사이트를 호스팅할 수 있다고 배웠는데요. 하지만 요즘 웹 개발에서 HTML, CSS, JavaScript를 직접 작성하는 일은 드물죠? 대부분 React와 같은 프론트엔드 라이브러리와 Vite와 같은 빌드 도구를 사용하여 HTML, CSS, JavaScript를 생성해낼 것입니다. 이번 포스팅에서는 웹 프로젝트를 GitHub Actions를 사용하여 빌드하고, 빌드 결과물을 바로 GitHub Pages에 배포하는 방법에 대

ngrok으로 로컬 서버를 인터넷에 공개하기

ngrok으로 로컬 서버를 인터넷에 공개하기

웹 애플리케이션을 개발하다 보면 로컬에서 실행 중인 서버를 외부에서 접속할 수 있게 해야 할 때가 있습니다. 예를 들어, 작업 중인 결과물을 클라이언트나 동료에게 시연해야 하거나, 외부 서비스(예: GitHub, Stripe, Slack)의 웹훅(Webhook)을 테스트해야 하는 경우가 그렇죠. 매번 클라우드 서버에 배포하는 것은 번거롭고 시간도 오래 걸립니다. 공유기 설정을 건드려서 포트 포워딩을 하는 것도 보안상 위험할 수 있고요. 이럴 때 가장 간편하게 사용할 수 있는 도구가 바로 ngrok입니다. ngrok은 로컬 컴퓨터의

GitHub Pages에 커스텀 도메인 연결하기

GitHub Pages에 커스텀 도메인 연결하기

GitHub Pages로 웹사이트 무료 호스팅하기에서 살펴봤듯이, GitHub Pages에 웹사이트를 배포하면 기본적으로 github.io 서브 도메인을 무료로 제공해주는데요. 대부분의 개인 프로젝트에서는 GitHub Pages의 기본 도메인을 사용해도 큰 지장이 없을 것입니다. 하지만 비즈니스를 위한 웹사이트를 호스팅할 때는 브랜딩이나 SEO(검색 엔진 최적화) 차원에서 커스텀 도메인을 원하게 되죠. 이번 포스팅에서는 간단한 실습을 통해서 GitHub Pages에 배포한 웹사이트에 커스텀 도메인을 연결하는 방법을 알려드리겠습니다.

GitHub Pages로 웹사이트 무료 호스팅하기

GitHub Pages로 웹사이트 무료 호스팅하기

GitHub Pages는 깃허브에서 코드 저장소에 딸려오는 무료 호스팅 서비스입니다. GitHub Pages를 사용하면 정적 웹사이트, 블로그, 포트폴리오, 프로젝트 문서 등을 아주 손쉽게 웹에 배포할 수 있죠. 이번 포스팅에서는 간단한 실습을 통해서 GitHub Pages에 웹사이트를 배포하는 가장 기초적인 방법을 알려드리겠습니다. GitHub Pages란? GitHub Pages는 깃허브 저장소에 올려놓은 프로젝트를 최소한의 노력으로 웹에 호스팅해주는 서비스입니다. 깃허브에서 거의 초창기부터 무료로 제공하고 있는데 은근히 모르시

OAuth Client Credentials: 사용자 없는 M2M 인증 제대로 이해하기

OAuth Client Credentials: 사용자 없는 M2M 인증 제대로 이해하기

지금까지 OAuth를 이야기할 때는 늘 사용자가 주인공이었습니다. 인가 코드(Authorization Code) + PKCE 흐름에서 봤듯이, 사용자가 로그인하고 동의하면 그 사용자를 대신할 토큰이 발급되는 식이었죠. 그런데 현실에는 로그인할 사람이 아예 없는 통신도 많습니다. 새벽 3시에 도는 결제 배치 작업이 결제 API를 호출하고, 백엔드 서비스 A가 내부 서비스 B의 API를 두드리고, CI 파이프라인이 배포 API를 부르는 상황을 떠올려 보세요. 여기엔 브라우저도, 동의 화면도, 사용자도 없습니다. 이렇게 서버가 서버를 부

OAuth 2.0 엔드포인트 제대로 이해하기

OAuth 2.0 엔드포인트 제대로 이해하기

OAuth 2.0을 처음 배울 때는 "인가 코드(authorization code)를 받아서 액세스 토큰(access token)으로 바꾼다"는 큰 그림만 머리에 담아두어도 충분한데요. 하지만 실제로 연동을 구현하거나 디버깅하는 단계로 넘어가면, 어떤 엔드포인트에 어떤 파라미터를 어떤 조건으로 보내야 하는가가 성패를 좌우합니다. "동의 화면까지는 뜨는데 토큰 교환에서 invalid_grant가 뜬다", "리다이렉트가 자꾸 invalid_redirect_uri로 거부된다" 같은 이슈는 거의 전부 특정 엔드포인트의 파라미터 규약을 놓쳐

OAuth Authorization Code + PKCE 흐름 단계별로 이해하기

OAuth Authorization Code + PKCE 흐름 단계별로 이해하기

OAuth를 배우다 보면 결국 이 문장을 자주 만나게 됩니다. 사용자 로그인이 있으면 인가 코드(Authorization Code) + PKCE를 쓰세요. 맞는 말인데, 처음 구현할 때는 막상 손에 잘 잡히지 않습니다. code는 어디서 오고, code_verifier는 누가 들고 있어야 하고, state는 PKCE와 다른 건지 헷갈리거든요. 동의 화면까지는 잘 뜨는데 콜백에서 invalid_grant가 나거나, 토큰 교환에서 redirect_uri가 다르다고 거부되는 일도 흔합니다. 이 글에서는 인가 코드 + PKCE 흐름을 요청

OAuth Grant Type 한 번에 정리하기

OAuth Grant Type 한 번에 정리하기

OAuth를 공부하다 보면 "인가 코드 흐름(Authorization Code Flow)을 써라", "클라이언트 자격 증명(Client Credentials)은 서버 간 통신용이다", "암묵적 흐름(Implicit)은 이제 쓰지 마라" 같은 말을 자주 듣게 됩니다. 처음에는 다 같은 OAuth처럼 보이는데, 왜 이렇게 flow가 여러 개인지 헷갈리기 쉽죠. 사실 스펙 관점에서 더 정확한 이름은 흐름(flow)보다 **그랜트 유형(grant type)**입니다. 클라이언트가 어떤 근거(grant)를 가지고 액세스 토큰(access t

gcloud CLI 사용법: 터미널에서 Google Cloud 다루기

gcloud CLI 사용법: 터미널에서 Google Cloud 다루기

Google Cloud Console에서 VM 하나 만들려고 브라우저를 열고, 프로젝트를 전환하려고 또 클릭하고, 배포 상태를 확인하려고 다시 페이지를 새로고침하고... 이런 경험 없으신가요? gcloud는 Google Cloud의 공식 CLI 도구입니다. Compute Engine, Cloud Storage, Cloud Run, BigQuery 같은 주요 서비스를 터미널 명령어 하나로 다룰 수 있어서 브라우저 없이도 클라우드 리소스를 관리할 수 있는데요. 셸 스크립트나 CI/CD 파이프라인에서도 그대로 쓸 수 있어서 자동화에도 딱

All Contributors로 오픈소스 기여자를 멋지게 인정해주기

All Contributors로 오픈소스 기여자를 멋지게 인정해주기

오픈소스 프로젝트를 운영하다 보면 코드 기여자에게만 공을 돌리기 쉽습니다. 하지만 문서 작성, 번역, 버그 리포트, 디자인, 아이디어 제안 등 다양한 방식으로 프로젝트에 기여하는 분들도 많죠. 이런 다양한 기여자들을 빠짐없이 인정해주고 싶은데, 어떻게 해야 할까요? 🤔 이번 포스팅에서는 All Contributors라는 도구를 소개해드리려고 합니다. All Contributors는 코드 기여뿐만 아니라 모든 형태의 기여를 인정하자는 철학을 담은 명세(specification)이자, 이를 자동화해주는 봇과 CLI 도구입니다. All

JWK와 JWKS 제대로 이해하기

JWK와 JWKS 제대로 이해하기

JWT를 검증하려면 서명을 확인할 공개 키가 필요한데요. 그런데 그 공개 키, 도대체 어떤 형식으로 표현하고 어떻게 주고받을까요? 전통적으로는 X.509 인증서나 PEM 같은 형식을 썼지만, JSON 기반인 JOSE 생태계에는 키를 위한 전용 형식이 따로 있습니다. 바로 **JWK(JSON Web Key)**입니다. 키 하나를 JWK로 표현하고, 여러 JWK를 묶으면 **JWKS(JWK Set)**가 되는데요. OAuth/OIDC에서 인가 서버가 공개 키를 배포할 때 쓰는 그 꾸러미가 바로 JWKS입니다. 이 글에서는 JWK가 무엇

CSS의 :has() 가상 클래스 사용법

CSS의 :has() 가상 클래스 사용법

CSS에서 자식이나 후손 요소는 아주 쉽게 선택할 수 있지만, 부모나 조상 요소를 선택하는 것은 불가능한 일이 었습니다. 그래서 오랫동안 자바스크립트를 동원해서 이러한 문제를 해결하곤 했었죠. 하지만 CSS에 :has() 가상 클래스가 추가되면서 이것도 이제 옛말이 되었습니다. 웹 개발자들이 많이 기다렸던 만큼 2023년 State of JS 설문 조사 가장 많이 채택된 기능으로 뽑히고도 했었죠. 이번 포스팅에서는 비교적 최근에 CSS에 추가된 기능인 :has() 가상 클래스를 어떻게 사용하는지 알아보도록 하겠습니다. 본 포스팅은

자바스크립트의 groupBy() API 사용법

자바스크립트의 groupBy() API 사용법

데이터를 특정 기준에 따라 분류하는 것은 자바스크립트로 데이터 처리를 할 때 자주 필요한 작업인데요. 그런데 아직도 데이터 그룹화를 위해서 reduce() 함수나 Lodash 라이브러리를 사용하시나요? 이번 포스팅에서는 자바스크립트에서 데이터를 그룹화를 위해 쓸 수 있는 비교적 새로운 API인 groupBy()에 대해서 알아보도록 하겠습니다. 기존 데이터 그룹화 방법 우선 예전에 자바스크립트에서 데이터 그룹화가 얼마나 불편했는지 살펴볼까요? 다음과 같이 여러 사용자의 이름, 나이, 국가를 담은 배열이 주어졌을 때, 아래와 같이 국가

Discord