(6.2) 권한주기(Auth State & Private Routes)_
영어쌤이 만드는 회원가입, 인증[CRUD] 만들어욤! 리액트와 파이썬 장고
안녕하세요? 죠니입니다. 바로 시작할게요!
- 아직까진 Add Lead(data 생성)과 Lead list(data list) 페이지가 숨겨지지 않고 전면에 공개되어 있습니다. 있어서는 안될 일이죠.
- 그래서 당연하지만 인증 받은 계정으로 접속시에만 해당 기능이 가능한 페이지로 넘기도록 작업을 할 것 입니다.
(10) Lead data 생성 화면 숨기기
입니다.
시작!
(10) /src/components/common/PrivateRoute.js 파일 생성 및 작성
- Lead data 생성 및 리스트 페이지 숨기기 // 권한을 가진 계정만 접근 가능
- 필요한 기능들 가져오기
- 다음을 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import React from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";
const PrivateRoute = ({ component: Component, auth, ...rest }) => (
<Route
{...rest}
render={props => {
return <Component {...props} />;
}}
/>
);
const mapStateToProps = state => ({
auth: state.auth
});
export default connect(mapStateToProps)(PrivateRoute);
|
cs |
(11) /src/components/App.js 에 Private Route 추가
- Private Route 기능을 App.js 파일로 가지고 오게 합니다.
- 그리고 다음과 같이 보호하길 위하는 페이지를 <PrivateRoute> 로 감싸줍니다.
- 실질적으론 일반적인 <Route> 를 <PrivateRoute> 로 수정해 주면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
// App.js
import React, { Component, Fragment } from "react";
import ReactDOM from "react-dom";
import { HashRouter as Router, Route, Switch, Redirect } from "react-router-dom";
import { Provider as Alert Provider } from 'react-alert';
import AlertTemplate from 'react-alert-template-basic';
import Header from "./layout/Header";
import Dashboard from "./leads/Dashboard";
import Alerts from "./layout/Alerts";
import Login from "./accounts/Login";
import Register from "./account/Register";
import PrivateRoute from ".common/PrivateRoute";
import { Provider } from "react-redux";
import store from "../store";
// Alert Options
const alertOptions = {
timeout: 3000,
position: 'top center'
}
class App extends Component {
render() {
return (
<Provider store={store}>
<AlertProvider template={AlertTemplate}
{...alertOptions}>
<Router>
<Fragment>
<Header />
<Alerts />
<div className="container">
<Switch>
<PrivateRoute exact path="/" component={Dashboard} />
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
</Switch>
</div>
</Fragment>
</Router>
</AlertProvider>
</Provider>
);
}
}
|
cs |
(12) /src/components/common/PrivateRoute.js 수정
- Priovate Route를 통해 페이지를 숨겼다면 이제는 인증을 받은 계정만이 접근할 수 있게 해야 한다는 개념이 들어가야 합니다.
- 다음과 같이 PrivateRoute.js 파일을 수정해 주세요.
- 위와 같이 인증이 되었는지에 대해 작성을 마치고 저장을 한 뒤 Redux tool을 활용해 확인을 하면 다음과 같은 결과를 얻을 수 있습니다.
- 그리고 페이지를 새로고침 하면 인증을 받지 않은 상태에선 다음과 같이 로그인 페이지로 Redirect됩니다. 바로 연결된다는 것 입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// /src/components/common/PrivateRoute.js
import React from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";
const PrivateRoute = ({ component: Component, auth, ...rest }) => (
<Route
{...rest}
render={props => {
if(auth.isLoading) {
return <h2>Loading...</h2>
} else if(!auth.isAuthenticated) {
return <Redirect to="/login" />;
} else {
return <Component {...props} />;
}
}}
/>
);
const mapStateToProps = state => ({
auth: state.auth
});
export default connect(mapStateToProps)(PrivateRoute);
|
cs |
(13) /src/actions/types.js 코드 추가 작성 || 사용자 계정 로그인 유무 판별
- 우리는 지금 REST API를 만들고 있습니다.
- 그렇기에 사용자가 지금 로그인이 되어있는 상태인지 아닌지를 판별해야 합니다.
- 목표는 다음과 같습니다.
- 사용자가 인증을 받았는지 확인
-- 토큰이 있다면 토큰을 fetch(가지고 오는 것)한다
- 인증을 받았다면 user loaded, 아니라면 auth error가 나게 합니다.
1
2
3
4
5
6
7
8
9
|
// /src/actions/types.js
export const GET_LEADS = "GET_LEADS";
export const DELETE_LEAD = "DELETE_LEAD";
export const ADD_LEAD = "ADD_LEAD";
export const GET_ERRORS = "GET_ERRORS";
export const CREATE_MESSAGE = "CREATE_MESSAGE";
export const USER_LOADING = "USER_LOADING";
export const USER_LOADED = "USER_LOADED";
export const AUTH_ERROR = "AUTH_ERROR";
|
cs |
(14) /src/reducers/auth.js
- 다음과 같이 사용자 계정 인증과 실패에 대한 코드를 추가 작성 해줍니다.
- 그리고 default 코드 위에 다음의 코드도 작성해 줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
// src/reducers/auth.js
import {
USER_LOADING,
USER_LOADING,
AUTH_ERROR
} from '../actions/types';
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: null,
isLoading: false,
user: null
}
export default function(state = initialState, action) {
switch(action.type) {
case USER_LOADING:
return {
...state,
isLoading: true
}
case USER_LOADING:
return {
...state,
isAuthenticated: treu,
isLoading: false,
user: action.payload
}
case AUTH_ERROR:
localStorage.removeItem('token');
return {
...state,
token: null,
user: null,
isAuthenticated: false,
isLoading: false
};
default:
return state;
}
}
|
cs |
(15) /src/actions/auth.js 생성 및 작성
- 인증을 위한 동작에 대한 코드를 작성합니다.
- auth.js 에는 작성할 코드들로 인증 동작을 실행합니다.
- Postman을 활용하여 테스트를 했을 때와 같은 동작이라고 보시면 되고 실제 코드에 쓸 내용도 Postman의 그것과 매우 유사합니다.
- 코드를 마저 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
// /src/actions/auth.js
import axios from 'axios';
import { returnErrors } from './messages';
import {
USER_LOADED,
USER_LOADING,
AUTH_ERROR
} from './types';
// CHECK TOKEN & LOAD USER
export const loadUser = () => (dispatch, getState) => {
// User Loading
dispatch({ type: USER_LOADING });
// Get token from state
const token = getState().auth.token;
// Headers
const config = {
headers: {
'Content-Type': 'application/json'
}
}
// If token, add to headers config
if(token) {
config.headers['Authorization'] = `Toekn ${token}`;
}
axios.get('/api/auth/user', config)
.then(res => {
dispatch({
type: USER_LOADED,
payload: res.data
});
}).catch(err => {
dispatch(returnErrors(err.response.data,
erro.response.state));
dispatch({
type: AUTH_ERROR
});
});
}
|
cs |
(16) /src/components/App.js 코드 추가 작성
- 동작을 위한 코드도 작성하였으니 그 동작을 이제 App.js로 가져와 반영합니다.
결과화면
- Redux tool로 결과를 확인합니다.
- /src/actions/auth.js 에서 작성한 것과 같이 User loading, auth error, get error 등이 불러와 졌습니다.
이렇게 해서 제 6장인 Auth State & Private Routes가 마무리 되었습니다.
다음 포스팅은
7장 Frontend Authentication 입니다. 간략히 내용을 언급하겠습니다.
- Login Functionality(로그인 기능)
- Login - get a token (토큰 발급 받기)
- Token 확인이 되어 인증 받기
잠시 쉬었다가 마지막 장을 위해 돌아오겠습니다.