City At Night

[MernStack] Blog 만들기 17. [React] Login API 만들기. 본문

MernStack

[MernStack] Blog 만들기 17. [React] Login API 만들기.

Wuny 2021. 6. 22. 02:23
728x90
반응형


1. axios 다운로드 및 authSaga 작성
로그인은 서버와 통신을 하는 작업이므로 서버와 통신을 도와주는 'axios' 라는 라이브러리를 다운로드한다.

$> npm i axios 

client 루트에서 다운로드하는걸 까먹지 말자.
redux/sagas/authSaga.js생성한다.

[authSaga.js]

import axios from 'axios';

//Login Api만들기
const loginUserAPI = (loginData) => {
    console.log(loginData, "loginData") //loginData가 어떤값으로 들어오는지 console.log를 찍어 확인한다
    const config = {
        headers: {
            "Content-Type" : "application/json"
        }
    }
    return axios.post('api/auth', loginData, config)
}

}

 

loginUserAPI라는 함수를 만들고 loginData를 파라미터값으로 받는다.
headers: {~} 이 부분은 우리가 서버작업을 할때 포스트맨드로 테스트할때 그 형식이다.(기억이 가물가물)
로그인은 서버로 데이터를 전송하기때문에 
return axios.post 를 적어주고 3개의 정보를 보낸다. (api/auth,loginData,config)
1. 'api/auth' 인증정보의 주소 (현재는 localhost:3000)
2. loginData 
3. config 데이터의 형식.(?) // 사실 이건 잘 감이 안온다.

 

2.로그인에 관한 generator함수 작성


[authSaga.js]

import { all, put, takeEvery,call,fork } from 'redux-saga/effects';
import { LOGIN_FAILURE, LOGIN_REQUEST, LOGIN_SUCCESS } from "../types";

그 다음 all,put,takeEvery,call,fork를  불러와주다.
(all,put,takeEvery,call,fork 에 대한 설명_ 클릭

저번 포스팅에서 만들어놓은 로그인에 관한 처리 type도 import 해준다.

function* loginUser(action) { 
    try{
        const result = yield call(loginUserAPI,action.payload) //action.payload??가 뭐지?
        console.log(result)
        yield put({
            type : LOGIN_SUCCESS,
            payload: result.data
        })
    }catch(e){
        yield put({
            type: LOGIN_FAILURE,
            payload: e.response
        })
    }
}

 

function* 은 generator함수인데  yeild함수를 사용할 수 있다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/function*
yeild를 사용하여 여러개의 값을 순서에따라 반환 할 수 있다.

try문 안에는 로그인에 성공했을때 catch문 안에는 로그인에 실패했을때 처리를 해준다.


3. 로그인 상황을 처리하는 함수 작성


[authSaga.js]

function* watchLoginUser(){
    yield takeEvery(LOGIN_REQUEST, loginUser)
}

watchLoginUser 라는제네레이터 함수를 작성한다. 
이 함수는 계속 로그인 요청을 기다리다 takeEvery 메서드를 사용하여
LOGIN_REQUEST가 들어오면 loginUser를 실행시킨다.



지금까지 작성했던 authSaga.js는  리덕스 패턴으로 많이 사용된다.
<지금까지 패턴>
1.  watchLoginUser함수가 LOGIN_REQUEST를 받고 loginUser함수로 던져준다.
2.  loginUser함수는  LOGIN_REQUEST를 받고 성공 또는 실패에 대한 처리를 한다.
3.  성공일시 loginUserAPI 함수로 던져준다.
4.  loginUserAPI는 서버로  로그인한 정보를 뿌려준다.


4. 모듈로 내보내기

[authSaga.js]

export default function* authSaga() {
    yield all([
        fork(watchLoginUser) //fork 함수
    ])
}

fork함수를 사용하여 모듈화한다.
//fork함수가 뭔지 봐보자.


5. sagas/index.js함수 작성

[sagas/index.js]

import {all,fork} from 'redux-saga/effects'
import axios from 'axios'

import authSaga from './authSaga'
import dotenv from 'dotenv'
dotenv.config()

axios.defaults.baseURL = process.env.REACT_APP_BASIC_SERVER_URL



export default function* rootSaga(){ //제네레이터 함수 .. 여러값을 반환할수 있음 .
    yield all([
        fork(authSaga)
    ]);
}

8번째 줄 axios.defaults.baseURL = process.env.REACT_APP_BASIC_SERVER_URL
이 부분은 .env로 작성하였다.
만약 .env로 작성 안하고 바로 서버 주소를 노출하게 된다면
axios.defaults.baseURL = http://localhost:7000 처럼 작성할 수 있다.
(지금은 로컬주소라 상관없지만 추후 배포시 문제가 생길 수 있다)
주소가 적나라게 보이면 보안에 취약할 수 있으니 닷엔브파일을 만들어 작성한다.

[client/.env]

REACT_APP_BASIC_SERVER_URL = "http://localhost:7000"

react로 만든 앱은 반드시 REACT_APP으로 시작한 다음 이름을 지어야한다.

 


[authSaga.js]  전체 코드

import axios from 'axios';
import { all, put, takeEvery,call,fork } from 'redux-saga/effects';
import { LOGIN_FAILURE, LOGIN_REQUEST, LOGIN_SUCCESS } from "../types";

//Login Api만들기
const loginUserAPI = (loginData) => {
    console.log(loginData, "loginData") //파라미터 체크
    const config = {
        headers: {
            "Content-Type" : "application/json"
        }
    }
    return axios.post('api/auth', loginData, config)
}

function* loginUser(action) { //function* 을 사용하면 yeild함수를 사용할 수 있다?
    try{
        const result = yield call(loginUserAPI,action.payload) //action.payload??가 뭐지?
        console.log(result)
        yield put({
            type : LOGIN_SUCCESS,
            payload: result.data
        })
    }catch(e){
        yield put({
            type: LOGIN_FAILURE,
            payload: e.response
        })
    }
}

function* watchLoginUser(){
    yield takeEvery(LOGIN_REQUEST, loginUser)
}
// 계속 로그인 리퀘스트를 받을 함수를 작성함
// takeEvery 계속 실행됨 
// LOGIN_REQUEST가 들어오면 loginUser를 실행시켜라

//여기까지가 리덕스 패턴으로 많이 사용됨

export default function* authSaga() {
    yield all([
        fork(watchLoginUser) //fork 함수
    ])
}

 

728x90
반응형
Comments