Post Gallery
Search

소셜 로그인은 모두 비슷한 과정
•
이전 카카오 로그인 구현과 결과적으로 동일한 과정을 거친다.
1.
인증 제공자(Provider)인 Google 디벨로퍼 콘솔에 접근해서 API 기능을 이용할 애플리케이션을 생성
2.
REST API 키 등 인증 키, 토큰 등을 받음
3.
해당 토큰과 함께 백엔드서버가 프로바이더 서버로 요청하는 중첩 구조를 만들게 됨
•
일반로그인 : 사용자 → 서버(서비스 서버) → 사용자
•
소셜로그인 : 사용자 → 서버(서비스 서버 → 프로바이더 서버 → 서비스 서버) → 사용자
•
실제 애플리케이션에서 구현하는 과정을 정리
[OAuth2.0] Google Social Login 구현 - 클라이언트 사이드 약식

클라이언트 약식 소셜 로그인(OAuth)을 백엔드 서버 중심 인증방식으로 변경
•
보안 및 관례상 프로덕션 환경에서는 Credential 획득 및 관리를 백엔드에서 처리하는 것이 일반적인 관례이자 더 안전한 방식
•
따라서 이전 클라이언트 사이드로 Credential을 전달하던 약식 구현에서 백엔드 중앙집중식 구현으로 변경하고자 한다.
[OAuth2.0] Google Social Login 구현 - 백엔드 중앙 관리식 로직 구현

문제 인식
HTTPS 배포를 통해 모든 서버들은 SSL을 통해 HTTPS 요청/응답을 받는 구조로 변경되고 있음
•
이 중 PixelStreaming을 하는 웹시그널링서버(WebRTC/Stun-Turn Server)가 동일한 도메인 인증서를 사용하면서 프론트엔드 서비스 내에 iFrame으로 PixelStreaming 화면을 임베딩 하는 부분의 오류가 발생
•
동일 오리진에 따른 문제
•
chrome-error://chromewebdata/:1 Refused to display 'https://metaverseacademy.site:8443/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.

해결 방안 탐색
해결 시도
•
보안을 위하여 다른 사이트에서 로드할 때 허용 범위가 지정되어 있다.
•
호출하는 사이트(A 프로젝트)는 호출 당하는 사이트(B 프로젝트)에서 막은거라 할 수 있는 일은 없다.
•
호출 당하는 사이트(B 프로젝트)에서 X-Frame-Options 설정을 해준다.
◦
DENY: 시도하는 사이트에 관계없이 페이지를 프레임에 표시 X
◦
SAMEORIGIN: 페이지는 모든 조상 프레임이 페이지 자체와 동일한 출처인 경우에만 표시
•
호출당하는 입장인 B 프로젝트에서 응답 헤더에 X-Frame-Options를 세팅해서 보내주어야 한다.
•
httpResponse.setHeader("X-Frame-Options", "allow-from A프로젝트 IP주소:포트번호");
httpResponse.setHeader("X-Frame-Options", "allow-from http://localhost:8080");
Java
복사
해결 시도와 결과
호출 당하는 입장인 Pixel Streaming의 서버에서 헤더 추가 설정 필요
•
아래는 SignalingWebServer의 cirrus.js의 부분이다.
•
해당 서버 프로젝트는 helmet은 HTTP 헤더를 설정하여 앱을 일반적인 웹 취약점으로부터 보호하는 데 도움이 되는 Express.js 미들웨어를 사용하고 있는 것으로 파악되었다.
if (config.UseHTTPS) {
app.use(helmet());
app.use(hsts({
maxAge: 15552000 // 180 days in seconds
}));
//Setup http -> https redirect
console.log('Redirecting http->https');
app.use(function (req, res, next) {
if (!req.secure) {
if (req.get('Host')) {
var hostAddressParts = req.get('Host').split(':');
var hostAddress = hostAddressParts[0];
if (httpsPort != 443) {
hostAddress = `${hostAddress}:${httpsPort}`;
}
return res.redirect(['https://', hostAddress, req.originalUrl].join(''));
} else {
console.error(`unable to get host name from header. Requestor ${req.ip}, url path: '${req.originalUrl}', available headers ${JSON.stringify(req.headers)}`);
return res.status(400).send('Bad Request');
}
}
next();
});
}
JavaScript
복사
•
실제로 파라미터로 UseHttps boolean을 받는 것으로 보아 HTTPS 사용 시에만 helmet 적용: helmet 미들웨어는 config.UseHTTPS 가 true 일 때만 활성화되고 있다.
•
helmet 설정 변경으로 helmet() 호출 시에 frameguard 옵션을 명시적으로 설정하여 X-Frame-Options 헤더의 동작을 변경하고자 한다.
1.
첫번째로 해당 부분이 실질적으로 위 문제를 발생시키는지 확인하기 위하여 frameguard 옵션 자체를 비활성화 해본다.
if (config.UseHTTPS) {
app.use(helmet({
frameguard: false // frameguard 미들웨어 비활성화
}));
app.use(hsts({
maxAge: 15552000 // 180 days in seconds
}));
JavaScript
복사


•
이를 통해 해당 helmet 미들웨어가 해당 부분을 제어하고 있는 것으로 파악되었다.
2.
이 상태로는 보안상 취약점을 발생 시킬 수 있으므로 명시적으로 해당 도메인에 대한 출처 허용으로 스코프를 좁히고자 한다.
if (config.UseHTTPS) {
app.use(helmet({
frameguard: false // frameguard 미들웨어 비활성화
}));
app.use((req, res, next) => {
res.setHeader(
"Content-Security-Policy",
`frame-ancestors 'self' https://metaverseacademy.site:443 https://www.metaverseacademy.site:443;`
);
next();
});
app.use(hsts({
maxAge: 15552000 // 180 days in seconds
}));
...
JavaScript
복사
이렇게 헤더를 추가 설정해준다. 이후 모바일로도 문제 없이 실행되는 모습

Refused to display in a frame because it set 'X-Frame-Options' to 'sameorigin'.

샘플 모습
1.
프론트엔드의 파일 업로드 요청 시작

2.
백엔드 컨트롤러의 요청 흐름
a.
(백엔드) 컨트롤러 요청 도착 → (백엔드) 파일 서비스 전달

b.
(백엔드) 파일 서비스 → (NAS) 파일 저장 서버 컨트롤러로 요청

c.
(NAS) 파일 저장 컨트롤러 → NAS 파일 서비스 → NAS 스토리지 내 저장

d.
(백엔드) 파일 정보 및 NAS 정적 서빙 경로 데이터베이스 저장

3.
프론트엔드의 파일 데이터베이스 목록 조회 화면

4.
강의실의 시청 화면 진입 모습

5.
시청 화면 요청 시 NAS의 웹서버로부터 서빙되는 영상의 모습


백엔드서버→NAS API 파일 업로드→NAS 영상 서빙 뷰 페이지 반환까지의 구현 샘플

문제 인식
•
문제 상태 분석
◦
개발PC에서 SSH로 NAS에 접근(특정 계정의 세션 ex)citefred 유저로 SSH세션 생성됨)
◦
파일업로드 관련 애플리케이션 실행(npm run start) - 해당 유저의 세션에서 실행되고 있음
◦
개발PC의 SSH로 접속한 터미널을 종료 또는 만료로 종료 되면 NAS에서도 해당 세션을 종료 시키면서 파일업로드 애플리케이션도 함께 종료됨
해결 방안 탐색
•
특정 유저가 로그인하는 방식의 SSH 세션은 결국 해당 접속을 종료하면 세션이 종료되면서 관련 프로세스가 모두 종료됨
•
따라서, NAS가 계속하여 실행되는 root 유저로 접근하면 해결 할 수 있지만 root계정으로 터미널에 접근하는 것을 개방하는 것은 위험성이 있음
•
NAS 자체에서 제공하는 Docker를 통해 실행하면 root에서 실행하는것이므로 지속적인 프로세스를 유지 할 수 있음
NAS 내 파일업로드 애플리케이션의 특정 SSH에 종속된 세션 만료 문제 + Docker와 Host의 컨텍스트 인식 문제

NAS 파일 스토리지를 활용하기
•
NAS:
◦
역할: 대용량 스토리지로서 AWS S3의 스토리지 서비스 역할 대체
◦
Nginx:
▪
역할: NAS의 정적 파일을 서빙
▪
기능: AWS S3의 정적 파일 URL 제공 역할 대체
◦
NAS 내부 파일 서버 애플리케이션:
▪
역할: NestJS API로 파일 시스템 전용 서버
기능: 서비스 백엔드 서버의 파일 시스템(I/O) 기능이 독립화된 별도 서비스
▪
매개체 역할: NAS와 서비스 백엔드 서버 간의 파일 관련 매개체 역할 수행 (리버스 프록시)
•
서비스 백엔드 서버:
◦
역할: NestJS 기반의 서비스 관련 API 서버
◦
기능: 웹 애플리케이션의 기본적인 CRUD 기능 제공
◦
데이터 저장: 파일 경로를 데이터베이스에 URL Path 형태로 저장
•
서비스 프론트엔드 서버:
◦
역할: 웹 애플리케이션의 전체 뷰 페이지 렌더링 담당
◦
기능: 백엔드 API와 통신을 통한 동적 페이지 렌더링
파일 제공: 각종 파일은 백엔드로부터 전달받는 URL Path를 통해 제공
NAS 파일서버 구축과 웹서버(Nginx)를 통한 파일 서빙

데이터 바인딩을 위한 @Input 데코레이터
@input 데코레이터를 통한 데이터 바인딩
Angular에서 데이터 바인딩을 위한 데코레이터는 주로 @Input()을 사용하여 부모 컴포넌트로부터 값을 받아오는 데 사용됩니다. 이 데코레이터는 자식 컴포넌트에서 부모 컴포넌트의 데이터를 바인딩할 수 있게 해줍니다.
다음은 Angular에서 @Input() 데코레이터를 사용하여 데이터 바인딩을 구현하는 간단한 예시입니다.
1.
자식 컴포넌트 생성
먼저 자식 컴포넌트를 생성하고, @Input()을 사용하여 데이터를 받을 준비를 합니다.
Angular의 @Input 데코레이터 사용 방법

Standalone?
Standardalone?
Angular에서 "Standalone" 컴포넌트는 Angular 14 이상에서 도입된 기능으로, 모듈 없이 독립적으로 사용할 수 있는 컴포넌트를 의미합니다. 이는 컴포넌트의 재사용성과 관리성을 높이며, 더 간편하게 애플리케이션을 구성할 수 있게 해줍니다.
Standalone 컴포넌트의 특징
1.
모듈 불필요: 기존의 Angular 컴포넌트는 반드시 모듈에 포함되어야 했지만, Standalone 컴포넌트는 독립적으로 사용할 수 있습니다.
컴포넌트의 standalone의 필요성과 적용 범위 고려

도메인 구매 후, DNS 관리페이지 -> A Record 설정 -> 서버 외부 IP 연결
•
두개의 접근 주소 HTTP 일반 배포 상태 확인 (이후 → SSL 발급 후 HTTPS 보안 배포로 연결)

자체 서버(로컬) HTTPS 배포를 위한 WACS를 통한 자체 Let’s Encrypt 인증서 발급과 연결

간단한 쇼핑몰 개발 기능목록
•
회원기능
◦
회원가입
◦
회원목록 조회
•
상품기능
◦
상품등록
◦
상품수정
◦
상품조회
•
주문기능
◦
상품주문
◦
주문내역조회
◦
주문취소
•
기타 요구사항
◦
상품은 재고관리가 필요
◦
상품의 종류는 도서, 음반, 영화로 구분
◦
상품을 카테고리로 구분 할 수 있음
◦
상품 주문시 배송 정보를 입력 할 수 있음
도메인 모델과 데이터베이스 설계
[Boot+JPA] 요구사항 분석 및 설계
Load more