Skip to content

Instantly share code, notes, and snippets.

@hoony-o-1
Last active November 25, 2017 15:53
Show Gist options
  • Save hoony-o-1/fefe9a9db0c780e1dce25048da635e0f to your computer and use it in GitHub Desktop.
Save hoony-o-1/fefe9a9db0c780e1dce25048da635e0f to your computer and use it in GitHub Desktop.
import request from 'superagent'
import AppDispatcher from '../AppDispatcher'
import * as types from '../constants'
import APIS from '../../../apis'
export default {
validateCurrentToken: function (options = {}) {
const currentToken = window.localStorage.getItem('TOKEN')
return new Promise((resolve, reject) => {
if (currentToken) {
request('GET', '/validate-token')
.send({
token
})
.end((err, res) => {
if (err) {
AppDispatcher.dispatch({
type: types.FAILED_AUTHORIZATION
})
// 현재 웹스토리지에 저장된 토큰은 유효하지 않으므로 삭제한다.
window.localStorage.removeItem('TOKEN')
reject()
} else {
// 현재 웹스토리지에 저장된 토큰은 유효하므로 state에 저장한다.
AppDispatcher.dispatch({
type: types.SET_TOKEN,
token: res.body.token
})
resolve(res.body)
}
})
} else {
// 현재 웹스토리지에 토큰이 없는 경우 인증 실패로 간주한다.
AppDispatcher.dispatch({
type: types.FAILED_AUTHORIZATION
})
reject()
}
})
},
logout: function () {
AppDispatcher.dispatch({
type: types.LOGOUT
})
window.localStorage.removeItem('TOKEN')
}
}
import { ReduceStore } from 'flux/utils'
import assign from 'object-assign'
import AppDispatcher from '../AppDispatcher'
import * as types from '../constants'
class AuthStore extends ReduceStore {
getInitialState () {
return {
token: ''
}
}
reduce (state, action) {
switch (action.type) {
case types.SET_TOKEN:
return assign({}, state, {
token: action.token
})
case types.LOGOUT:
case types.FAILED_AUTHORIZATION:
return assign({}, state, {
token: 'FAILED_AUTHORIZATION'
})
default:
return state
}
}
}
export default new AuthStore(AppDispatcher)
import React, { Component } from 'react'
import { Container } from 'flux/utils'
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'
import AuthStore from './AuthStore'
import AuthActions from './AuthActions'
import ProtectedRouteContainer from 'Containers/ProtectedRouteContainer'
import LoadingComponent from 'Components/LoadingComponents'
class RouterContainer extends Component {
componentWillMount () {
AuthActions.validateCurrentToken() // 로컬 스토리지에 토큰이 저장되어 있는지를 확인하고 있다면 서버를 통해 인증 작업을 진행하는 액션
}
render () {
const ProtectedRoute = ({ Component, path, ...rest }) => {
switch (this.state.token) {
case '': // 사이트에 처음 접속하여 Store에 아무것도 저장되어 있지 않은 상태에서 보호된 경로에 접속한 경우 로딩 화면을 띄운다
return <DefaultLayout path={path} Component={LoadingComponent} />
case 'FAILED_AUTHORIZATION': // 로컬 스토리지에 토큰이 저장되어 있지 않거나 서버에서 토큰 인증에 실패할 경우 로그인 화면으로 리다이렉트
return <Redirect to="/login" />
default: // 토큰 인증에 성공한 경우 정상적으로 원하는 컴포넌트를 불러온다
return <DefaultLayout {...rest} path={path} component={Component} />
}
}
const DefaultLayout = ({ Component, ...rest }) => (
<Route {...rest} render={props => <Component {...props} />} />
)
return (
<Router>
// Normal Route
<DefaultLayout exact strict path="/normal-route" Component={ NormalRouteContainer } />
// Protected Route
<ProtectedRoute exact strict path="/protected-route" Component={ ProtectedRouteContainer } />
</Router>
)
}
}
RouterContainer.getStores = () => ([AuthStore])
RouterContainer.calculateState = (prevState) => ({
...AuthStore.getState()
})
export default Container.create(RouterContainer)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment