앱스토어 출시까지 고려하고 있기 때문에, firebase를 이용해 소셜 로그인을 구현해서 보안과 개발편의성 두마리 토끼를 다 잡을 생각이다 ^^
React Native 클라이언트에서 Firebase Auth API를 사용하여 사용자를 인증하고, 백엔드(Express + Firebase Admin SDK)에서 해당 토큰을 검증하는 방식!
// Firebase Admin SDK 초기화
const serviceAccount = require('../path-to-your-service-account-key.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
// 미들웨어: Firebase 토큰을 검증하는 함수
const verifyFirebaseToken = async (req: any, res: any, next: any) => {
const idToken = req.headers.authorization?.split('Bearer ')[1];
if (!idToken) {
return res.status(401).send('Authorization token missing');
}
try {
const decodedToken = await admin.auth().verifyIdToken(idToken);
req.user = decodedToken;
next();
} catch (error) {
res.status(401).send('Unauthorized');
}
};
app.post('/signup', verifyFirebaseToken, (req: Request, res: Response) => {
const user = req.user; // Firebase에서 인증된 사용자 정보
// 추가로 회원 정보 저장을 원한다면 DB에 사용자 정보 저장 등의 작업 수행 가능
res.status(201).json({ message: 'User signed up successfully', user });
});
app.post('/login', verifyFirebaseToken, (req: Request, res: Response) => {
const user = req.user; // Firebase에서 인증된 사용자 정보
res.status(200).json({ message: 'User logged in successfully', user });
});
auth middleware에서 Request 에 유저 정보를 담아주고자 하기 때문에, 타입을 확장시켜야한다.
// /src/types/express/index.d.ts
import { User } from "firebase/auth";
declare global {
namespace Express {
interface Request {
user?: User;
}
}
}
{
"compilerOptions": {
// ...
"typeRoots": ["./src/types", "./node_modules/@types"]
},