본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


앵귤러, 리엑트, 뷰/Angular Tutorial(new)

앵귤러 튜토리얼(Angular tutorial) - 27, with FireBase : 권한, 파일

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2020. 9. 10.

이번시간에도 이어서 파일업로드와 관련한 내용을 살펴보겠습니다.
그 전에 먼저 권한과 관련된 내용을 언급하고 넘어가겠습니다.

파이어베이스에서 권한과 관련된 설정을 우리는 "모두허용" 상태로 사용하였습니다.
"모두허용" 상태이기 때문에 사실 인증과 관련된 내용은 넘어갔었습니다.

파이어베이스에서는 어느정도 까지는 해당 상태를 허용해 주지만 나중에 시간이 지나고 나면 보안수준이 낮기 때문에 모든 요청을 막아버릴수도 있습니다.
그러므로 "읽기"는 모두 허용 하지만 "변경"과 관련된 행위는 권한을 갖도록 해 주어야 합니다.
일반적으로 보안수준은 Rules라는 탭을 선택하여 설정 할 수 있습니다.

파이어베이스 웹 콘솔로 이동하여 아래 사진처럼 Rules를 선택하여 변경하도록 합니다.

* 파이어스토어, 저장소 2개 다 바꾸어 주세요.

Storage나 Cloud Firestore를 선택하면 Rules라는 탭이 존재 합니다!!

 

위 사진처럼 읽는 것은 모두 허용 하지만, 데이터베이스를 변경하는 행위는 권한이 있어야 하는 것을 일반적인 권한으로 설정합니다.
이렇게 하고나면 데이터를 가져오는 것에서는 문제가 없지만 쓰기, 수정 및 삭제를 하는 경우에는 문제가 발생 합니다.

퍼미션 오류입니다..?

 

이러한 경우를 대비하기 위해서 이제 설정방법에 대해서 살펴 보겠습니다.
먼저 모듈에 기능을 추가하여 줍니다.

* 대상 : app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { BoardComponent } from './board/board.component';

import { RouterModule,Routes} from '@angular/router'; //라우터
import { AuthGuard } from './auth.guard';
import { AskService } from './ask.service';
import { FormsModule  } from '@angular/forms';

import { AngularFireModule } from '@angular/fire';
import { AngularFirestoreModule } from '@angular/fire/firestore';
import { AngularFireStorageModule } from '@angular/fire/storage';  //저장소 모듈
import { BUCKET } from '@angular/fire/storage';  //저장소 관련 버킷

import { AngularFireAuthModule } from '@angular/fire/auth';  //권한 모듈!!!!


const fireEnvironment = {
  production: true,
  firebase: { /** 설 정 값 */ }
}

const router : Routes = [  //라우팅
  {path : 'login' , component : LoginComponent},  
  {path : 'board' , component : BoardComponent, canActivate:[AuthGuard]},  //가드 추가
  {path : '', redirectTo : '/login',  pathMatch : 'full'}
]

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AngularFireModule.initializeApp(fireEnvironment.firebase, '/'),  
    AngularFirestoreModule,  
    AngularFireStorageModule,
    AngularFireAuthModule,  //권한 모듈!!!!
    RouterModule.forRoot(router,{enableTracing:false})
  ],
  providers: [
    AskService,
    { provide: BUCKET, useValue: fireEnvironment.firebase.storageBucket }  //버킷을 등록 합니다.
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

 

권한 모듈인 AngularFireAuthModule을 추가하여 줍니다.
다음 단계로는, 파이어 베이스에 등록,수정,삭제와 같은 행위가 이루어 질 경우에 앱이 허용된 인원 인지를 확인이 필요합니다.
그리고 만약 허용되어있지 않으면 인증을 요청해야 합니다.

  * 절차 : 허용된 인원 확인 -> (아닐경우) 인증요청 -> 데이터 변경

 

샘플 코드를 app컴포넌트에 붙여보았습니다.

* 대상 : app.component.ts

import { Component } from '@angular/core';
import { AskService } from './ask.service';
import { AngularFireAuth } from '@angular/fire/auth';


@Component({
  selector: 'app-root',
  template : '<router-outlet></router-outlet>',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'thirdStudy';

  constructor(private service : AskService, public auth: AngularFireAuth ) {   
    //1. 등록함수
    //service.addItem("board",{number:6,hello:'hello',today:new Date()});


    //권한 수준을 높이는 경우에 대한 대비
    this.auth.user.subscribe(arg => {
      if (arg == undefined || arg == null) {
        this.auth.signInWithEmailAndPassword('구글메일주소', '메일 비밀번호').then(res => {
          console.log(res);
          //쓰기, 수정, 삭제등 행위 입력
        })
      } else {
          //쓰기, 수정, 삭제등 행위 입력
      }
    });


    //2. 가져오는 함수
    // service.getItem("board").valueChanges({idField: 'idx'}).subscribe( arg => {
    //   console.log(arg);
    // });   

    //3. 수정함수
    //service.updateData('board',{number:10, new_text:'hello updater1'},'OHW97JhpZeCB6dEp7KXo');
    //service.updateData('board',{number:10, new_text:'hello updater2'},'OHW97JhpZeCB6dEp7KXo');

    //3. 수정함수 간단한 타입
    //service.updateData2('board',{new_text:'하이'},'OHW97JhpZeCB6dEp7KXo');

    //4. 수정함수 set 타입
    //service.updateData3('board',{new_text:'하이'},'OHW97JhpZeCB6dEp7KXo');

    //5. 삭제
    //service.deleteData('board','OHW97JhpZeCB6dEp7KXo');
  }  

}

 

app컴포넌트에서 생성자를 주목하여주세요.

AngularFireAuth 클래스에서 user라는 값을 가져와 구독하여 실행하였습니다.

맨 처음 구독 결과로 null 값이 나옵니다.
해당 앱은 아직 사용자 인증을 받지 않았다는 뜻 입니다.


인증이 되어있지 않는 앱이면, signInWithEmailAndPassword 함수를 사용하여 사용자 인증을 해 주도록 합니다.

함수 이름처럼 이메일과 비밀번호를 통해서 인증하도록 하였습니다.
사용자 인증이 완료되고 난 이후에 본인의 등록, 수정, 삭제 함수가 동작하도록 해 주면 끝 입니다.
이미 인증되어있는데 다시 인증을 하면 오류가 발생하므로 주의하여 주세요.

 

마지막 단계로, 우리가 동작시키고 있는 앵귤러가 이메일과, 비밀번호를 가지고 파이어베이스를 사용 할 수 있도록 권한을 추가하여줍니다.

다시 파이어베이스 웹 콘솔로 이동하여 아래 사진처럼 설정을 바꾸어 줍니다.

이메일/비밀번호를 통해서 인증할 예정이므로 사용설정을 해 주도록 합니다.

 

사진처럼 Authentication 탭을 누르고 Sign-in method 탭을 누르면 "로그인 제공업체" 목록을 만나게 됩니다.
우리는 이메일과 비밀번호를 사용하여 인증을 할 예정 이므로 사진처럼 이메일/비밀번호를 사용하도록 변경하여 줍니다.

처음에 해당 내용을 소개하지 않는 이유는 규칙 설정과, 허용권한 설정이 다소 햇갈릴 수 있었기 때문 입니다.
앵귤러와 파이어베이스를 통해서 프로젝트를 실제 서비스 할 예정이라면 권한설정을 잊지말고 해 주어야 합니다.

권한과 관련하여 간단하게 정리하여 보겠습니다.
1. 파이어베이스 웹 콘솔 : 데이터를 읽는 것은 모두 허용, 변경하는 행위는 권한이 있도록 Rule탭에서 규칙을 변경하여 줍니다.(파이어스토어, 파이어스토리지 둘다)
2. 파이어베이스 웹 콘솔 : Authentication 탭을 누르고 Sign-in method 탭에서 인증 규칙을 추가하여 줍니다.
3. 앵귤러 : app모듈에서 AngularFireAuthModule을 등록하여 줍니다.
4. 앵귤러 : 등록, 수정, 삭제 시 app컴포넌트에 있는 인증 단계를 걸친 이후에 동작하도록 코드를 수정 합니다.

 

다시 파일 업로드와 관련된 내용입니다!
업로드한 파일을 다운로드 받는 방법은 무척 쉽습니다.
저장소 객체에서 ref함수를 불러와주면 간단하게 해결 됩니다.

board컴포넌트와 관련된 2개의 파일을 아래와 같이 수정 하겠습니다.

* 대상 : board.component.ts

import { Component, OnInit } from '@angular/core';
import { AngularFireStorage } from '@angular/fire/storage';


@Component({
  selector: 'app-board',
  templateUrl: './board.component.html',
  styleUrls: ['./board.component.css']
})
export class BoardComponent implements OnInit {

  private file;
  private path = "good/";  //경로

  url;  //a테그에게 줄 주소 값

  constructor(private storage: AngularFireStorage) { 
    this.storage.ref('/good/histogram.png').getDownloadURL().subscribe( arg=>{
      console.log(arg)
      this.url = arg;
    });     
  }

  ngOnInit(): void {
    
  }

  uploadFile(event) {
    this.file = event.target.files[0];
  }

  send(){
    const ref = this.storage.upload(this.path + this.file.name, this.file);
    console.log(ref);
  }

}

 

* 대상 : board.component.html

<p>board works!</p>
<input type="file" (change)="uploadFile($event)">
<input type="button" (click)="send()" value='전송'>

<br>
<a href='{{url}}' target="_blank" download>다운로드</a>

 

생성자에 파일 다운로드의 모습을 올려놓았습니다.
ref함수를 통해서 getDownloadURL함수를 다시 호출한 뒤에 구독하도록 하였습니다.
해당 구독한 내용이 바로 저장된 파일의 웹 주소 입니다.
해당 웹주소를 a테그를 통해서 다운로드 받도록 하였습니다.

 

화면에서 다운로드 버튼을 누르면 파일이 다운로드 받아지는 게 아니라 새탭에서 열리는 것을 볼 수 있습니다.
왜냐하면 파이어베이스에서 파일 다운로드 하는 것은 크로스도메인과 관련된 문제가 존재하기 때문 입니다.
파일 다운로드를 강제로 구현하려면 크게 4단계로 이루어 집니다.
1. 구글sdk를 설치 합니다.
2. sdk를 통해 로그인을 합니다.
3. cors와 관련된 파일을 작성합니다.
4. 해당 파일을 sdk의 명령어를 통해서 업로드 합니다.

 

해당방법은 사실 권장하는 방식은 아니여서 아래 링크로 소개만 하겠습니다.
파일 다운로드와 관련된 내용은 중반이후에 나와있습니다.

lts0606.tistory.com/190

 

앵귤러 튜토리얼 (Angular tutorial) -26 with 파이어 베이스

* 제가 다시 작성한 최신 튜토리얼 수정본 입니다. 아래 주소를 통해서 진행하시는 것을 권장 드립니다. ^^ lts0606.tistory.com/328 앵귤러 튜토리얼(Angular tutorial) - 1 안녕하세요. 앵귤러에 대해서 알�

lts0606.tistory.com

가급적 파일 다운로드를 하는 경우에는 백그라운드 서버에서 요청하여 가져오는 것을 권장 드립니다.

 

마지막으로 파일삭제 입니다.
파일 삭제도 어렵지 않습니다.

* 대상 : board.component.ts

  //생략..
  constructor(private storage: AngularFireStorage) { 
    /*this.storage.ref('/good/histogram.png').getDownloadURL().subscribe( arg=>{
      console.log(arg)
      this.url = arg;
    }); */    
    this.storage.ref('/good/histogram.png').delete();  //삭제입니다.
  }
  //생략..

 

네, 저거 한줄이 끝입니다. 
그렇게 어렵지 않으므로 설명을 줄이겠습니다.
여기까지 파이어베이스와의 연동과 관련된 내용이 대략적으로 끝났습니다.
미처 정리하지 못한 파일저장과 관련된 함수, 인증 관련된 함수는 직접 정리해서 멋진 서비스를 만들어 보시기를 희망합니다.

다음 시간에는 앵귤러와 관련하여 조금더 세부적인 내용에 대해서 살펴보겠습니다.

thirdStudy.zip
0.01MB

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글