프론트엔드 심화 2주차

zero_0·2021년 8월 12일
0

FE 학습

목록 보기
7/22
post-thumbnail


이번 주차 너무 힘들었어...
결국 다 듣긴 했지만 낡고 지쳐버렸지ㅋㅋㅋ


콜백 헬

꼬리에 꼬리를 무는 비동기 처리가 늘어나면 호출이 계속 중첩되고, 코드가 깊어지고, 관리는 어려워집니다. 이런 깊은 중첩을 콜백 헬이나 멸망의 피라미드라고 부릅니다

프라미스

비동기 연산이 종료된 이후 결과를 알기 위해 사용하는 객체입니다!
프라미스를 쓰면 비동기 메서드를 마치 동기 메서드처럼 값을 반환할 수 있어요.
전통적인 콜백 패턴으로 인한 콜백 헬 때문에 ES6에서 도입한 또다른 비동기 처리 패턴입니다.
비동기 처리 시점을 좀 더 명확하게 표현할 수 있어요!
프라미스 생성

프라미스는 Promise 생성자 함수(new 키워드 기억하시죠!)를 통해 생성합니다.

// 프라미스 객체를 만듭니다. 
// 인자로는 (resolve, reject) => {} 이런 excutor 실행자(혹은 실행 함수라고 불러요.)를 받아요.
// 이 실행자는 비동기 작업이 끝나면 바로 두 가지 콜백 중 하나를 실행합니다.
// resolve: 작업이 성공한 경우 호출할 콜백
// reject: 작업이 실패한 경우 호출할 콜백
const promise = new Promise((resolve, reject) => {
	if(...){
		...
		resolve("성공!");
	}else{
		...
		reject("실패!");
	}
});

프라미스의 상태값

  • pending: 비동기 처리 수행 전(resolve, reject가 아직 호출되지 않음)
  • fulfilled: 수행 성공(resolve가 호출된 상태)
  • rejected: 수행 실패(reject가 호출된 상태)
  • settled: 성공 or 실패(resolve나 reject가 호출된 상태)

프라미스 후속 처리 메서드

.then(성공 시, 실패 시)
then의 첫 인자는 성공 시 실행, 두번째 인자는 실패 시 실행됩니다. (첫 번째 인자만 넘겨도 됩니다!)

async, await

앞으로 정말정말 많이 보고 쓸 문법입니다.
프라미스 사용을 엄청 편하게 만들어줘요! 🙂
[더 알면 좋은 내용]
강의에서 다루지 않지만 제네레이터라는 함수와 이터러블을 알면 더더 좋습니다.

  1. async

    • 함수 앞에 async를 붙여서 사용합니다.
    • 항상 프라미스를 반환합니다. (프라미스가 아닌 값이라도, 프라미스로 감싸서 반환해줘요!)
    // async는 function 앞에 써줍니다.
    async function myFunc() {
    	return "프라미스를 반환해요!"; // 프라미스가 아닌 걸 반환해볼게요!
    }
    
    myFunc().then(result => {console.log(result)}); // 콘솔로 확인해봅시다!
  2. await

    • async의 짝꿍이에요. (async 없이는 못씁니다!)
    • async 함수 안에서만 동작합니다.
    • await는 프라미스가 처리될 때까지 기다렸다가 그 이후에 결과를 반환해요!
    async function myFunc(){
    	let promise = new Promise((resolve, reject) => {
    		setTimeout(() => resolve("완료!"), 1000);
    	});
    
        console.log(promise);
    
    	let result = await promise; // 여기서 기다리자!하고 신호를 줍니다.
    
        console.log(promise);
    
    	console.log(result); // then(후처리 함수)를 쓰지 않았는데도, 1초 후에 완료!가 콘솔에 찍힐거예요.
    }

    await를 만나면, 실행이 잠시 중단되었다가 프라미스 처리 후에 실행을 재개합니다!
    즉, await를 쓰면 함수 실행을 기다리게 하는거예요.

토큰 기반 인증

예전에는 사용자의 로그인 상태를 서버가 전부 가지고 있었어요. 서버의 세션에 사용자 정보를 넣고 이 사람이 로그인을 했다 안했다를 전부 기록하고 기억했습니다.로그인한 사용자가 많아지면 서버에 부하가 많이 오겠죠? -> 세션 기반 인증
그렇다고 서버를 여러개 놓자니 관리가 까다로워지고요.
→ 그래서 최근에는 오늘 배울 토큰 기반 인증 방법을 많이 사용해요! (토큰 :나만을 위한 합격 목걸이)

OAuth2.0(오어th스 2.0)

외부서비스의 인증 및 권한부여를 관리하는 프레임워크입니다!

  • OAuth 동작 방식 (간단 ver.)
  1. 클라이언트서버 사이에 인증(로그인)을 하면 서버가 access_token 을 줍니다.
  2. 클라이언트access_token을 이용해서 API 요청을 할 수 있어요.
  3. 서버는 API 요청을 받고, access_token을 가지고 권한이 있나 없나 확인해서 결과를 클라이언트에 보내줍니다.

JWT(Json Web Token)

토큰의 한 형식입니다! 데이터가 JSON 형태로 이루어져 있는 토큰이에요.
=> 전자서명이 포함된 토큰, 좀 더 보안이 좋음
생김새 : [header].[payload(내용)].[signature(서명)]

  • 동작 방식 : 토큰 기반 동작 방식대로 움직여요!
    • 유저가 로그인을 시도하면,
    • 서버가 요청을 확인하고 secret key를 가지고 access_token을 발급합니다.
    • 클라이언트에 JWT를 전달하고
    • 클라이언트는 API 요청을 할 때 Authorization header에 JWT를 담아서 보냅니다.
    • 서버는 JWT의 서명을 확인하고 payload에서 정보를 확인해서 API 응답을 보냅니다.

JWT vs OAuth?
JWT와 OAuth는 로그인에 많이 쓰이는 두 인증 방식입니다.
뭘 택할지 자주 고민하게 되지만 사실 비교하긴 조금 애매해요.
JWT는 토큰의 한 형식이고 OAuth는 프레임워크거든요.
(OAuth에서 토큰으로 JWT를 사용할 수도 있고요. 🙂 )

웹 저장소(feat. 토큰)

쿠키
클라이언트 로컬에 저장되는 key:value 형태의 저장소입니다!
약 4KB 정도 저장할 수 있어요

세션 스토리지
HTML5에서 추가된 저장소입니다! 쿠키와 마찬가지로 key:value 형태의 저장소예요.세션 스토리지에 저장된 데이터는 브라우저를 닫으면 제거돼요!

로컬 스토리지

  • 로컬 스토리지는 따로 지워주지 않으면 계속 브라우저에 남아 있어요.
    → 유저의 아이디, 비밀번호같은 중요한 정보를 넣어두면 아주 위험해요!

  • 왜 쿠키보다 로컬 스토리지에 저장했을까?
    • 쿠키보다 더 많은 정보를 저장할 수 있다.
      (쿠키 4KB, 로컬 스토리지 5MB)
    • 쿠키처럼 모든 http 통신에 딸려들어가지 않는다.
  • 그럼 무조건 로컬 스토리지에 토큰을 넣을까?
    • 아니요! 로컬 스토리지는 말그대로 로컬에 데이터가 다 남아있으니 보안상 취약해지기 쉬워요.
      프로젝트 성향에 맞춰 저장 장소는 그때그때 달라져야 합니다.
    • 우리는 쿠키에 저장할거예요. 😉

리덕스 설치

로그인 상태를 리덕스에 저장하고 어떤 컴포넌트에서든 편히 볼 수 있게 해봐요.

이건 리덕스와 리덕스 모듈 내에서 경로 이동까지 하게 해줄 히스토리, 라우터와 히스토리를 엮어줄 모듈까지 한번에 설치해보는 거예요.

yarn add redux react-redux redux-thunk redux-logger history@4.10.1 connected-react-router@6.8.0

유저 모듈 만들기

설치한 redux-actions와 immer를 사용해서 액션과 액션 생성 함수, 리듀서를 만드는 방법, 알아봅시다!

immer는 불변성 관리를 , redux-actions는 좀 더 편한 액션 관리를 위해 사용해요.

Q. 왜 불변성 관리하는데 패키지까지 써야하나요?
A. 객체는 const로 선언해도 내용이 수정될 수 있죠! 그래서 스프레드 문법 ({...어떤 것} 이렇게 쓰는 거!) 등을 이용해서 수정되지 않게 주의해서 코드를 작성합니다.
그런데, 객체 구조가 복잡해지면 코드를 짜기가 번거로워요. 그래서 불변성을 신경 쓰지 않는 것처럼 써도 알아서 불변성을 유지해주는 immer를 사용하는거예요.

  • [시작하기 전에 잠깐!]
    항상 폴더부터 만들고 시작해야해요! src 폴더 아래에 redux폴더, 그리고 그 아래에 modules 폴더를 만들어주세요.

Firebase Authentication

파이어베이스 설치
yarn add firebase

  • shared/firebase.js에서 auth 설정
import firebase from "firebase/app";
import "firebase/auth";

const firebaseConfig = {
// 인증정보!
};

firebase.initializeApp(firebaseConfig);
const auth = firebase.auth();

export { auth };

회원가입 구현하기

순서가 중요💫
1. firebase.js에 만들어둔 auth 가져오기
2. 리덕스에서 signupFB 함수 만들기
3. auth.createUserWithEmailAndPassword()로 가입 시키기
4. Signup 컴포넌트에서 signupFB를 호출!
5. 가입한 후, display_name 바로 업데이트하기
6. 사용자 정보 업데이트 후에 메인 페이지로 이동하기

로그인 구현하기

순서가 중요💫
1. firebase.js에 만들어둔 auth 가져오기
2. 리덕스에서 loginFB 함수 만들기
3. auth.signInWithEmailAndPassword()로 로그인 💌공식문서 참고
4. Login 컴포넌트에서 loginFB를 호출!
5. 리덕스의 user 정보 업데이트 후에 메인 페이지로 이동하기

로그인 유지하기

이제 쿠키에 로그인 유무를 저장하지 않죠! 파이어베이스 auth를 통해 관리하고 있으니까요. 🙂
그럼, 페이지가 새로고침 되었을 때 로그인은 어떻게 유지하면 좋을까?

  1. 로그인 시, 세션에 로그인 상태를 기록하도록 바꿔줍니다
  2. firebase 인증 키를 export 해줍니다.
  3. 세션을 체크해서 로그인 상태를 유지합시다!
  4. 혹은? 파이어베이스를 통해 로그인 한 상태가 맞나 확인해야죠!
    맞다면 → 유저 정보를 가져다가 넣어줘야하니까요!

로그아웃 구현하기

파이어베이스 인증에서 제공하는 로그아웃 함수 호출하기

  • logout하기

    // redux/modules/user.js
    const logoutFB = () => {
      return function (dispatch, getState, {history}) {
        auth.signOut().then(() => {
          dispatch(logOut());
          history.push("/");
        });
      };
    };

정규식 써서 이메일 체크하기

학교에서 배운 정규식 나와서 반가워 하는 중ㅋㅋ (❁´◡`❁)


점점 모양이 나오는 중이다 ㅎㅎ쿠헤헷

profile
차근차근 채워가는 it일지

0개의 댓글