728x90
개략
Firebase에서 도메인, API, IP의 관계를 설명해드리겠습니다:
Firebase 서비스와 도메인
- Firebase Hosting
- Firebase가 제공하는 고유 도메인(예: your-app-name.web.app 또는 your-app-name.firebaseapp.com)을 통해 웹 앱을 호스팅합니다.
- 사용자 정의 도메인(예: yourdomain.com)을 연결할 수도 있습니다.
- Firebase Functions
- Functions는 https://region-your-project-id.cloudfunctions.net/your-function-name 형태의 URL로 접근합니다.
- Hosting과 연결하면 your-app-name.web.app/api/... 같은 경로로도 Functions에 접근 가능합니다.
API 접근 제어
- Firebase Authentication
- 사용자 인증을 통해 API 접근을 제한할 수 있습니다.
- 토큰 기반 인증으로 API 요청을 보호합니다.
- Cloud Functions for Firebase
- API 키나 인증 토큰으로 접근을 제한할 수 있습니다.
- 기본적으로 누구나 접근 가능하지만, 코드 내에서 인증 로직을 구현해 제한할 수 있습니다.
IP 기반 제한
- Functions의 IP 제한
- Firebase Functions 자체에는 IP 제한 기능이 내장되어 있지 않습니다.
- 이전에 보여드린 코드처럼 Express 미들웨어를 사용해 수동으로 IP 필터링을 구현해야 합니다.
- Cloud IAM과 VPC 서비스 제어
- 엔터프라이즈 수준의 Firebase/Google Cloud 계정에서는 VPC 서비스 제어를 통해 IP 제한을 설정할 수 있습니다.
- 이는 일반 Firebase 플랜에서는 제공되지 않는 고급 기능입니다.
실제 작동 방식
- 사용자가 Firebase Functions API에 요청을 보냅니다.
- 요청은 Firebase의 서버를 통과합니다.
- 요청이 Functions 코드에 도달합니다.
- 코드 내 미들웨어(우리가 작성한 IP 체크 코드)가 요청 IP를 검사합니다.
- 허용된 IP라면 처리를 계속하고, 그렇지 않으면 거부합니다.
따라서 IP 제한을 위해서는 Firebase 프로젝트 설정이 아닌 Functions 코드 수준에서 구현해야 합니다. 특별한 API를 가져오는 것이 아니라, 요청 객체에서 IP 정보를 추출하고 이를 검증하는 방식입니다.
......................................................................................
실제 작동방식 예시& 상세 설명
PHP 서버와 웹뷰 앱에서 FCM 푸시 알림 구현 흐름
PHP 서버로 개발된 웹을 모바일 앱의 웹뷰로 표시하고, Firebase Cloud Messaging(FCM)을 통해 푸시 알림을 구현하는 상황에 맞게 설명해드리겠습니다.
전체 아키텍처 구성
- PHP 웹 서버: 사용자에게 웹 콘텐츠 제공 및 관리자 기능 제공
- 모바일 앱: 웹뷰를 통해 PHP 웹 콘텐츠를 표시
- Firebase Functions: FCM 푸시 알림 전송을 위한 API 제공
- Firebase Cloud Messaging(FCM): 실제 푸시 알림 전송 서비스
실제 작동 방식
1. 토큰 등록 과정
- 모바일 앱 설치 및 실행:
- 사용자가 앱을 설치하고 실행합니다.
- 앱 내부에서 FCM으로부터 디바이스 토큰을 발급받습니다.
// 앱 내 웹뷰의 JavaScript 코드
firebase.messaging().getToken().then((token) => {
// 토큰을 PHP 서버로 전송
fetch('https://your-php-server.com/register-token.php', {
method: 'POST',
body: JSON.stringify({ token: token })
});
});
2. PHP 서버에서 토큰 저장:
// register-token.php
<?php
$data = json_decode(file_get_contents('php://input'), true);
$token = $data['token'];
// 데이터베이스에 토큰 저장
$sql = "INSERT INTO user_tokens (token, created_at) VALUES (?, NOW())";
$stmt = $pdo->prepare($sql);
$stmt->execute([$token]);
echo json_encode(['success' => true]);
?>
2. 푸시 알림 발송 과정
- PHP 관리자 페이지에서 푸시 발송 요청
// send-push.php (관리자 페이지)
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = $_POST['title'];
$body = $_POST['body'];
$link = $_POST['link'];
// Firebase Functions API 호출
$ch = curl_init('https://us-central1-your-project.cloudfunctions.net/api/send-push');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'title' => $title,
'body' => $body,
'link' => $link
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
// 결과 처리
}
?>
2.Firebase Functions에서 IP 검증 후 FCM 발송:
- PHP 서버의 IP가 203.0.113.42라고 가정합니다.
// Firebase Functions index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const cors = require('cors');
admin.initializeApp();
const app = express();
app.use(cors({ origin: true }));
// PHP 서버 IP만 허용
app.use((req, res, next) => {
const clientIP = req.headers['x-forwarded-for']?.split(',')[0].trim();
console.log(`접근 IP: ${clientIP}`);
if (clientIP === '203.0.113.42') {
next();
} else {
res.status(403).json({
success: false,
message: '승인되지 않은 IP입니다.'
});
}
});
app.post('/send-push', async (req, res) => {
const { title, body, link } = req.body;
try {
// 웹뷰 앱 사용자들의 FCM 토큰 가져오기
const tokensSnapshot = await admin.firestore().collection('user_tokens').get();
const tokens = [];
tokensSnapshot.forEach(doc => {
if (doc.data().token) tokens.push(doc.data().token);
});
if (tokens.length === 0) {
return res.status(400).json({ success: false, message: '발송 가능한 디바이스가 없습니다.' });
}
// FCM 메시지 구성
const message = {
notification: { title, body },
data: { link: link || '' },
tokens: tokens
};
// 푸시 발송
const response = await admin.messaging().sendMulticast(message);
res.json({
success: true,
message: `${response.successCount}개 발송 성공, ${response.failureCount}개 실패`
});
} catch (error) {
res.status(500).json({ success: false, message: error.message });
}
});
exports.api = functions.https.onRequest(app);
3. 사용자 디바이스에서 알림 수신 및 처리
- 푸시 알림 수신:
- 사용자 디바이스가 FCM으로부터 푸시 알림을 수신합니다.
- 알림이 표시되고, 사용자가 알림을 탭하면 앱이 열립니다.
- 웹뷰에서 알림 처리:
// 앱의 웹뷰 JavaScript 코드
firebase.messaging().onMessage((payload) => {
// 앱이 포그라운드 상태일 때 알림 표시
const { title, body } = payload.notification;
const link = payload.data.link;
// 사용자에게 알림 표시 또는 링크 처리
if (link) {
window.location.href = link;
}
});
IP 제한의 중요성
이 구조에서 IP 제한이 중요한 이유는:
- 보안: PHP 서버의 IP만 허용함으로써 승인되지 않은 외부에서 푸시 알림 API를 호출하는 것을 방지합니다.
- 오용 방지: 악의적인 사용자가 API를 발견하고 불필요한 알림을 발송하는 것을 막습니다.
- 리소스 보호: Firebase Functions와 FCM의 할당량 및 비용을 관리하는 데 도움이 됩니다.
도메인, IP, API의 관계 요약
- 도메인: PHP 서버(예: your-php-server.com)에서 웹 콘텐츠를 제공하고, 관리자가 푸시 알림을 발송하는 인터페이스를 제공합니다.
- IP: PHP 서버의 고정 IP(203.0.113.42)는 Firebase Functions에서 허용 목록으로 관리되어, 해당 IP에서 오는 요청만 푸시 알림 API에 접근할 수 있습니다.
- API: Firebase Functions에서 제공하는 /send-push 엔드포인트는 FCM을 통해 실제 푸시 알림을 발송하는 기능을 제공합니다.
이러한 구조를 통해 PHP 웹 서버와 모바일 웹뷰 앱 간의 원활한 푸시 알림 시스템을 안전하게 구축할 수 있습니다.
728x90
'소프트랩스 > 비쨔' 카테고리의 다른 글
세션 (1) | 2025.04.08 |
---|---|
결제 intent 에러 (1) | 2025.04.03 |
ios 빌드번호 바꾸는법 (0) | 2025.03.25 |
PG사는 들어가지는데, 은행에서 결제 안들어가지는 이슈 - 헤더 개념 (0) | 2025.03.20 |
캐시와 쿠키의 차이 (1) | 2025.03.17 |