LMS Develop
Search

ν΄λΌμ΄μΈνΈ μ½μ μμ λ‘κ·ΈμΈ(OAuth)μ λ°±μλ μλ² μ€μ¬ μΈμ¦λ°©μμΌλ‘ λ³κ²½
β’
보μ λ° κ΄λ‘μ νλ‘λμ
νκ²½μμλ Credential νλ λ° κ΄λ¦¬λ₯Ό λ°±μλμμ μ²λ¦¬νλ κ²μ΄ μΌλ°μ μΈ κ΄λ‘μ΄μ λ μμ ν λ°©μ
β’
λ°λΌμ μ΄μ ν΄λΌμ΄μΈνΈ μ¬μ΄λλ‘ Credentialμ μ λ¬νλ μ½μ ꡬνμμ λ°±μλ μ€μμ§μ€μ ꡬνμΌλ‘ λ³κ²½νκ³ μ νλ€.
[OAuth2.0] Google Social Login ꡬν - λ°±μλ μ€μ κ΄λ¦¬μ λ‘μ§ κ΅¬ν

μμ λ‘κ·ΈμΈμ λͺ¨λ λΉμ·ν κ³Όμ
β’
μ΄μ μΉ΄μΉ΄μ€ λ‘κ·ΈμΈ κ΅¬νκ³Ό κ²°κ³Όμ μΌλ‘ λμΌν κ³Όμ μ κ±°μΉλ€.
1.
μΈμ¦ μ 곡μ(Provider)μΈ Google λ벨λ‘νΌ μ½μμ μ κ·Όν΄μ API κΈ°λ₯μ μ΄μ©ν μ ν리μΌμ΄μ
μ μμ±
2.
REST API ν€ λ± μΈμ¦ ν€, ν ν° λ±μ λ°μ
3.
ν΄λΉ ν ν°κ³Ό ν¨κ» λ°±μλμλ²κ° νλ‘λ°μ΄λ μλ²λ‘ μμ²νλ μ€μ²© ꡬ쑰λ₯Ό λ§λ€κ² λ¨
β’
μΌλ°λ‘κ·ΈμΈ : μ¬μ©μ β μλ²(μλΉμ€ μλ²) β μ¬μ©μ
β’
μμ
λ‘κ·ΈμΈ : μ¬μ©μ β μλ²(μλΉμ€ μλ² β νλ‘λ°μ΄λ μλ² β μλΉμ€ μλ²) β μ¬μ©μ
β’
μ€μ μ ν리μΌμ΄μ
μμ ꡬννλ κ³Όμ μ μ 리
[OAuth2.0] Google Social Login ꡬν - ν΄λΌμ΄μΈνΈ μ¬μ΄λ μ½μ

λ°μ΄ν° λ°μΈλ©μ μν @Input λ°μ½λ μ΄ν°
@input λ°μ½λ μ΄ν°λ₯Ό ν΅ν λ°μ΄ν° λ°μΈλ©
Angularμμ λ°μ΄ν° λ°μΈλ©μ μν λ°μ½λ μ΄ν°λ μ£Όλ‘ @Input()μ μ¬μ©νμ¬ λΆλͺ¨ μ»΄ν¬λνΈλ‘λΆν° κ°μ λ°μμ€λ λ° μ¬μ©λ©λλ€. μ΄ λ°μ½λ μ΄ν°λ μμ μ»΄ν¬λνΈμμ λΆλͺ¨ μ»΄ν¬λνΈμ λ°μ΄ν°λ₯Ό λ°μΈλ©ν μ μκ² ν΄μ€λλ€.
λ€μμ Angularμμ @Input() λ°μ½λ μ΄ν°λ₯Ό μ¬μ©νμ¬ λ°μ΄ν° λ°μΈλ©μ ꡬννλ κ°λ¨ν μμμ
λλ€.
1.
μμ μ»΄ν¬λνΈ μμ±
λ¨Όμ μμ μ»΄ν¬λνΈλ₯Ό μμ±νκ³ , @Input()μ μ¬μ©νμ¬ λ°μ΄ν°λ₯Ό λ°μ μ€λΉλ₯Ό ν©λλ€.
Angularμ @Input λ°μ½λ μ΄ν° μ¬μ© λ°©λ²

λ¬Έμ μΈμ
β’
λ¬Έμ μν λΆμ
β¦
κ°λ°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)λ₯Ό ν΅ν νμΌ μλΉ

λ¬Έμ μΈμ
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 μμ μλΉ λ·° νμ΄μ§ λ°νκΉμ§μ ꡬν μν

λλ©μΈ ꡬ맀 ν, DNS κ΄λ¦¬νμ΄μ§ -> A Record μ€μ -> μλ² μΈλΆ IP μ°κ²°
β’
λκ°μ μ κ·Ό μ£Όμ HTTP μΌλ° λ°°ν¬ μν νμΈ (μ΄ν β SSL λ°κΈ ν HTTPS 보μ λ°°ν¬λ‘ μ°κ²°)

μ체 μλ²(λ‘컬) HTTPS λ°°ν¬λ₯Ό μν WACSλ₯Ό ν΅ν μ체 Letβs Encrypt μΈμ¦μ λ°κΈκ³Ό μ°κ²°

Standalone?
Standardalone?
Angularμμ "Standalone" μ»΄ν¬λνΈλ Angular 14 μ΄μμμ λμ
λ κΈ°λ₯μΌλ‘, λͺ¨λ μμ΄ λ
립μ μΌλ‘ μ¬μ©ν μ μλ μ»΄ν¬λνΈλ₯Ό μλ―Έν©λλ€. μ΄λ μ»΄ν¬λνΈμ μ¬μ¬μ©μ±κ³Ό κ΄λ¦¬μ±μ λμ΄λ©°, λ κ°νΈνκ² μ ν리μΌμ΄μ
μ ꡬμ±ν μ μκ² ν΄μ€λλ€.
Standalone μ»΄ν¬λνΈμ νΉμ§
1.
λͺ¨λ λΆνμ: κΈ°μ‘΄μ Angular μ»΄ν¬λνΈλ λ°λμ λͺ¨λμ ν¬ν¨λμ΄μΌ νμ§λ§, Standalone μ»΄ν¬λνΈλ λ
립μ μΌλ‘ μ¬μ©ν μ μμ΅λλ€.
μ»΄ν¬λνΈμ standaloneμ νμμ±κ³Ό μ μ© λ²μ κ³ λ €