インターン生が挑んだ認証方式のマイグレーション──メルペイ加盟店管理画面へのOAuth 2.0導入

はじめに

こんにちは。メルペイPartner Platformチームでバックエンドエンジニアのインターンをしている@takiと申します。
この記事は、Merpay & Mercoin Advent Calendar 2025 の22日目の記事です。

Partner Platformチームではメルペイの加盟店向けの管理画面を開発しています。本記事では、インターン期間中に取り組んだタスクの一つである、管理画面の認証方式をマイグレーションした経験について紹介します。

背景

メルペイでは、加盟店向けに管理画面を提供しています。この画面では、店舗でのメルペイの取引履歴の確認など、さまざまな機能を利用できます。

既存の認証方式

現在の管理画面では、以下のようなフローの認証方式を採用しています。

  1. ログイン: お客さまが送信したメールアドレス・パスワードを用いて、加盟店管理画面側で認証を行います。
  2. リソース取得: 認証が成功するとアクセストークンが発行され、そのトークンを用いて依存先の各マイクロサービスにリクエストを行います。

このロジックはシンプルですが、大きな課題があります。それは、他サービス(例えばメルカリShopsやメルカリAdsなど)の加盟店管理画面とは独立した認証体系になってしまっているということです。

そのため、例えばメルペイとメルカリShopsの両方を利用している加盟店のスタッフは、それぞれのサービスの管理画面で異なるアカウントを発行する必要があります。

新しい認証方式

そこで今回、この課題の解決に向けて、認証方式のマイグレーションを行いました。新しい方式の基本的なフローは以下の通りです。

  1. ログイン: お客さまはまず認可サーバにメールアドレス・パスワードを送信し、認証を行います。ここで使用する認可サーバは、メルカリのIDPチームが提供しているものです。
  2. トークンを要求: 加盟店管理画面側から、認可用のトークンを認可サーバにリクエストします。
  3. トークンを発行: 認可サーバがトークンを発行します。
  4. リソース取得: 発行されたトークンを用いて、加盟店管理画面から依存先のマイクロサービスにアクセスします。

この方式では、認証・認可のフローが各サービスから分離され、共通の認可サーバに集約されます(下図参照)。これにより、将来的にはお客さまがさまざまなサービスの加盟店管理画面に、共通のアカウントでログインできるようになります。(メルカリShopsに関してはOAuthへのマイグレーションが別途で必要になります。)

この仕組みは、技術的にはOAuth 2.0およびOIDC(OpenID Connect)というプロトコルを使用しています。以下では、OAuth 2.0について簡単に説明します。

OAuth 2.0とは

OAuth 2.0は、サードパーティアプリケーションがお客さまのリソースに安全にアクセスするための認可(Authorization)プロトコルです。

OAuth 2.0の登場人物

OAuth 2.0では、以下の4つの登場人物が出てきます。

  • リソースオーナー(Resource Owner): リソースの所有者であるお客さま。今回のケースでは加盟店のスタッフです。
  • クライアント(Client): リソースにアクセスしたいアプリケーション。今回のケースでは加盟店管理画面(のBFF:Backend For Frontend)です。
  • 認可サーバ(Authorization Server): お客さまを認証し、アクセストークンを発行するサーバ。今回のケースではIDPチームが提供する認可サーバです。
  • リソースサーバ(Resource Server): 保護されたリソースを保持するサーバ。今回のケースでは加盟店管理画面から呼び出される各種マイクロサービスです。

OAuth 2.0のフロー

OAuth 2.0にはいくつかのフロー(グラントタイプ)があります。その中で、Webアプリケーションで最も一般的なのはAuthorization Code Flowというものです。今回実装したフローも、このフローを採用しています。

基本的な流れは以下の通りです。

  1. 認可リクエスト: お客さまがログインを試みると、クライアントはお客さまを認可サーバにリダイレクトし、認可を要求します。
  2. ログイン: 認可サーバでお客さまがログインします。
  3. 認可コードの発行: 認可サーバは認可コードを発行し、クライアントにリダイレクトします。
  4. トークンを要求: クライアントは認可コードを認可サーバに送信し、アクセストークンを要求します。
  5. トークンを発行: 認可サーバは、正当なクライアントからのリクエストかどうかを検証した上で、アクセストークンを発行します。
  6. リソース取得: クライアントはアクセストークンを使用して、リソースサーバのAPIにアクセスします。

先ほどの図ではこのフローを一部省略して描いていましたが、OAuth 2.0のフローを踏まえてちゃんと描くと以下のような形になります。

今回の開発内容

実装前の準備

実装に入る前に、まず要件を整理する必要がありました。具体的には、既存のロジックのどの部分をどの順序で変更するべきか調査し、チケットを切るところから始めました。

この際、参考にしたのがスキマバイト「メルカリ ハロ」の加盟店管理画面です。メルカリ ハロは最も早くOAuthによる認可を導入していたサービスでした。実際にメルカリ ハロの管理画面を触ってみた上で、メルカリ ハロへのOAuth導入時のドキュメント、および実装を照らし合わせながら理解することで、実装の進め方の解像度を大きく高めることができました。

残念ながらメルカリ ハロは2025年12月をもってサービスが終了しましたが、メルカリ ハロで行われたさまざまな技術的挑戦で得られた知見は、こうして他のプロダクトに生かし続けられるということを実感しました。

実装

実装の方針を立てた後、実際の開発に取り掛かりました。認可サーバ側の認証・認可のロジックはIDPチーム側で既に実装されていたため、今回の開発では加盟店管理画面のBFFにおける処理の実装がメインとなりました。具体的には、上の図の③のリダイレクトを受け付ける部分や、④⑤のトークン発行の部分などです。

OAuthのフローでは、加盟店管理画面のBFFは、ブラウザとの直接通信を多用します。例えば、ブラウザにリダイレクトを行わせたり、⑤で受け取ったアクセストークンをブラウザのCookieにセットしたりする必要があります。

そのため、これらの処理はサーバ間通信の仕組みであるgRPCサーバではなく、HTTPサーバで行うのが適切です。しかし、元々のBFFにはgRPCサーバしか存在しなかったため、新たにHTTPサーバを構築する必要がありました(下図の赤色部分)。

実装では、gRPCサーバと同一プロセス内の別ポートでHTTPサーバを立ち上げるようにしました。さらに、Kubernetesのポート公開の設定やGatewayのプロキシ設定を変更することで、無事にHTTPサーバを疎通させることができました。

続いて、新しく立てたHTTPサーバに、③や④⑤などのフローを行うためのエンドポイントを実装し、テスト環境でOAuthによる認可を動かすところまでを実現できました。

インターンの感想

メルペイでの約3ヶ月間のインターンを通して、強く感じたことは、メルペイのエンジニアは一般的なエンジニアの担当領域にとどまらず、事業側へのインパクトを解像度高く把握してプロダクトに関わっているということです。

実際、自分の周りのメンターの方々は、単に与えられた仕様を実装するのではなく、「自分の開発しているものが、お客さまにどのような価値をもたらし、その価値が事業の成長や収益にどうつながるのか」まで踏み込んで議論しながらプロダクトに向き合っていると感じました。

そういった視点を前提に、必要に応じて周囲のチームと連携しながら、仕様の見直しなども含めて主体的に開発を進めていく──このスタイルがマネージャー層だけでなく、一人ひとりのエンジニアにまで根付いていることは、自分にとって大きな驚きであり、とても魅力的な環境だと感じました。

そして、メルペイのエンジニアがこのような動きをできる理由の一つとして、メルカリ・メルペイにはVibe CodingやAgentic Codingが深く浸透しているということがあると感じました。「Coding Agentの登場によって、エンジニアの役割はアーキテクトへと変化していく」とはよく言われていることですが、メルカリではこの変化がすでにかなり進んでいると実感すると共に、自分もこのようなエンジニアを目指したいと感じる経験となりました。

終わりに

この記事では、メルペイのインターンで取り組んだ認証方式のマイグレーション、そしてインターンを通して感じたことをまとめました。

インターン期間中は、この記事で述べた内容に限らず、技術的な面でも、それ以外の面でも、さまざまな学びを得ることができました。

残りのインターン期間では、OAuthの導入に関するQAを実施し、本番環境へのリリースまで完了させたいと考えています。

明日の記事は@kubomiさんです。引き続きお楽しみください。

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加