| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- typescript
- Vite
- python
- 인증
- playwright
- contextBridge
- 상태관리
- 보안
- 프론트엔드
- php
- 크롤링
- JWT
- next.js
- 메일자동화
- FastAPI
- 마이그레이션
- REST API
- 온디바이스AI
- 아키텍처
- electron
- React
- Android
- javascript
- 배포
- Kotlin
- 백엔드
- github actions
- sqlite
- 도메인설계
- 소셜로그인
- Today
- Total
HM소프트
채용 플랫폼 백엔드 인증 구현 — 기본 인증 + SNS 소셜 로그인 (1) 본문

NestJS 인증 계층을 전역 가드와 공개 데코레이터로 기본값 잠김 구조로 설계하고, Passport 로컬·JWT 전략과 bcrypt 해싱으로 기본 인증을 구현한 과정을 다룬다. 접근·갱신 토큰을 분리 키로 발급하고, 소셜 로그인 3종의 외부 신원을 이메일 기준으로 한 사용자로 수렴시킨 채용 플랫폼 백엔드 설계 기록이다.
시리즈를 시작하며
구직자가 이력서를 쓰고, 기업이 채용 공고를 올리고, 둘을 잇는 채용 플랫폼을 만들었다. 프론트엔드·백엔드·AI 서비스가 분리된 구조라, 네 편으로 나눠 기록한다.
- (이 글) 백엔드 인증 — 기본 인증과 SNS 로그인
- 이력서·자기소개서·경력기술서 — 엔티티 설계와 파일 업로드
- 프론트엔드 — Next.js 15 + React 19, 지도 UI
- AI 오케스트레이터 — LLM으로 이력서 피드백·초안 생성
특정 서비스명·회사명은 빼고 구현만 다룬다. 1편은 모든 기능의 출발점인 인증이다.
기술 스택 (백엔드)
- 언어/프레임워크: TypeScript + NestJS
- 배포: Docker
- 인증: 기본 인증(이메일/비밀번호) + SNS 소셜 로그인
채용 플랫폼은 "누가 접속했는가"가 모든 기능의 전제다. 이력서, 지원 내역, 기업 정보 모두 인증된 사용자에 묶인다. 그래서 인증을 가장 먼저, 가장 탄탄하게 만들었다.
기본 인증부터
이메일/비밀번호 기반 기본 인증을 먼저 세웠다. NestJS의 모듈 구조를 활용해, 인증 관련 로직(가드, 전략, 토큰 발급)을 AuthModule로 묶었다.
@Module({
imports: [
UserModule,
JwtModule.register({ secret: process.env.JWT_SECRET, signOptions: { expiresIn: '1h' } }),
],
providers: [AuthService, JwtStrategy, LocalStrategy],
controllers: [AuthController],
})
export class AuthModule {}
NestJS의 가드(Guard)와 전략(Strategy) 패턴이 인증에 잘 맞았다. 라우트에 가드를 붙이면 그 라우트는 인증을 요구하고, 전략이 "어떻게 검증하느냐"를 담당한다.
@UseGuards(JwtAuthGuard)
@Get('me')
getProfile(@Req() req) {
return req.user; // 가드가 통과시킨 인증된 사용자
}
인증 상태(auth status) 다루기
기본 인증을 만든 뒤, "지금 로그인돼 있는가, 토큰이 유효한가"를 일관되게 다루는 부분을 정리했다. 프론트엔드가 "내 인증 상태"를 물을 수 있어야 하고, 토큰 만료·갱신이 매끄러워야 한다. auth status 처리를 보완해, 프론트가 현재 인증 상태를 신뢰성 있게 알 수 있게 했다.
SNS 소셜 로그인
채용 플랫폼은 "가입 장벽"이 전환율을 좌우한다. 이메일 가입만 있으면 이탈이 크다. 그래서 SNS 소셜 로그인을 붙였다.
소셜 로그인의 핵심은 외부 제공자가 인증해준 사용자를, 우리 시스템의 사용자와 잇는 것이다.
// SNS 콜백: 외부 프로필 → 우리 유저로 매핑(없으면 생성)
async validateSnsUser(profile: SnsProfile): Promise<User> {
const existing = await this.userService.findBySnsId(profile.provider, profile.id);
if (existing) return existing;
// 처음이면 우리 시스템 사용자로 생성
return this.userService.createFromSns(profile);
}
신경 쓴 지점:
- 계정 연결: 같은 사람이 이메일로도 가입하고 SNS로도 들어올 수 있다. 어떻게 한 사용자로 볼 것인가(이메일 기준 매칭 등).
- 최초 진입 처리: SNS 첫 로그인 시 우리 시스템 사용자를 자동 생성하되, 채용 플랫폼에 필요한 추가 정보(구직자/기업 구분 등)는 이후 단계에서 받는다.
- 토큰 발급: 외부 인증이 끝나면 우리 시스템의 토큰을 발급해, 이후 요청은 SNS와 무관하게 우리 토큰으로 돈다.
정리하며
1편의 핵심은 인증을 모든 기능의 신뢰 기반으로 세운 것이다.
- NestJS의 가드/전략 패턴으로 인증 로직을 모듈화.
- auth status를 일관되게 다뤄 프론트가 인증 상태를 신뢰.
- SNS 로그인으로 가입 장벽을 낮추되, 외부 계정과 내부 사용자의 매핑을 명확히.
다음 2편에서는 인증된 사용자에 묶이는 핵심 데이터, 이력서·자기소개서·경력기술서의 엔티티 설계와 파일 업로드를 다룬다.
'외주 개발일지' 카테고리의 다른 글
| LLM 오케스트레이터로 이력서 피드백·초안 생성 — 채용 플랫폼 (4) (0) | 2026.06.12 |
|---|---|
| 이력서·자기소개서 엔티티 설계와 파일 업로드 — 채용 플랫폼 (2) (0) | 2026.06.12 |
| Electron 키오스크 모드와 웹 데모 배포 — 현장 키오스크 개발기 (4) (0) | 2026.06.11 |
| Electron 하드웨어 연동 개발기 (3) — 스텁 드라이버와 IPC 상태 통합 (0) | 2026.06.11 |
| Konva 캔버스 디자인 편집기 — USB 이미지 연동까지, 현장 키오스크 개발기 (2) (0) | 2026.06.11 |