Showing
22 changed files
with
477 additions
and
43 deletions
... | @@ -6,6 +6,7 @@ | ... | @@ -6,6 +6,7 @@ |
6 | "@testing-library/jest-dom": "^4.2.4", | 6 | "@testing-library/jest-dom": "^4.2.4", |
7 | "@testing-library/react": "^9.3.2", | 7 | "@testing-library/react": "^9.3.2", |
8 | "@testing-library/user-event": "^7.1.2", | 8 | "@testing-library/user-event": "^7.1.2", |
9 | + "axios": "^0.19.2", | ||
9 | "immer": "^7.0.1", | 10 | "immer": "^7.0.1", |
10 | "include-media": "^1.4.9", | 11 | "include-media": "^1.4.9", |
11 | "open-color": "^1.7.0", | 12 | "open-color": "^1.7.0", |
... | @@ -17,6 +18,7 @@ | ... | @@ -17,6 +18,7 @@ |
17 | "redux": "^4.0.5", | 18 | "redux": "^4.0.5", |
18 | "redux-actions": "^2.6.5", | 19 | "redux-actions": "^2.6.5", |
19 | "redux-devtools-extension": "^2.13.8", | 20 | "redux-devtools-extension": "^2.13.8", |
21 | + "redux-saga": "^1.1.3", | ||
20 | "styled-components": "^5.1.1" | 22 | "styled-components": "^5.1.1" |
21 | }, | 23 | }, |
22 | "scripts": { | 24 | "scripts": { |
... | @@ -39,5 +41,6 @@ | ... | @@ -39,5 +41,6 @@ |
39 | "last 1 firefox version", | 41 | "last 1 firefox version", |
40 | "last 1 safari version" | 42 | "last 1 safari version" |
41 | ] | 43 | ] |
42 | - } | 44 | + }, |
45 | + "proxy": "http://localhost:4000" | ||
43 | } | 46 | } | ... | ... |
1 | import React from 'react'; | 1 | import React from 'react'; |
2 | import styled from 'styled-components'; | 2 | import styled from 'styled-components'; |
3 | import { Link } from 'react-router-dom'; | 3 | import { Link } from 'react-router-dom'; |
4 | -import Button from '../common/Button'; | ||
5 | import palette from '../../lib/styles/palette'; | 4 | import palette from '../../lib/styles/palette'; |
6 | -/* | 5 | +import Button from '../common/Button'; |
7 | -Display Auth Form(Register, Login) | ||
8 | -*/ | ||
9 | 6 | ||
10 | const AuthFormBlock = styled.div` | 7 | const AuthFormBlock = styled.div` |
11 | h3 { | 8 | h3 { |
... | @@ -47,9 +44,6 @@ const ButtonWithMarginTop = styled(Button)` | ... | @@ -47,9 +44,6 @@ const ButtonWithMarginTop = styled(Button)` |
47 | margin-top: 1rem; | 44 | margin-top: 1rem; |
48 | `; | 45 | `; |
49 | 46 | ||
50 | -/** | ||
51 | - * Show Error message | ||
52 | - */ | ||
53 | const ErrorMessage = styled.div` | 47 | const ErrorMessage = styled.div` |
54 | color: red; | 48 | color: red; |
55 | text-align: center; | 49 | text-align: center; | ... | ... |
... | @@ -38,7 +38,7 @@ const AuthTemplate = ({ children }) => { | ... | @@ -38,7 +38,7 @@ const AuthTemplate = ({ children }) => { |
38 | <AuthTemplateBlock> | 38 | <AuthTemplateBlock> |
39 | <WhiteBox> | 39 | <WhiteBox> |
40 | <div className="logo-area"> | 40 | <div className="logo-area"> |
41 | - <Link to="/">Jaksimsamil</Link> | 41 | + <Link to="/">작심삼일</Link> |
42 | </div> | 42 | </div> |
43 | {children} | 43 | {children} |
44 | </WhiteBox> | 44 | </WhiteBox> | ... | ... |
1 | +import React from 'react'; | ||
2 | +import styled from 'styled-components'; | ||
3 | +import Responsive from './Responsive'; | ||
4 | +import Button from './Button'; | ||
5 | +import { Link } from 'react-router-dom'; | ||
6 | + | ||
7 | +const HeaderBlock = styled.div` | ||
8 | + position: fixed; | ||
9 | + width: 100%; | ||
10 | + background: white; | ||
11 | + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08); | ||
12 | +`; | ||
13 | + | ||
14 | +const Wrapper = styled(Responsive)` | ||
15 | + height: 4rem; | ||
16 | + display: flex; | ||
17 | + align-items: center; | ||
18 | + justify-content: space-between; | ||
19 | + .logo { | ||
20 | + font-size: 1.125rem; | ||
21 | + font-weight: 800; | ||
22 | + letter-spacing: 2px; | ||
23 | + } | ||
24 | + .right { | ||
25 | + display: flex; | ||
26 | + align-items: center; | ||
27 | + } | ||
28 | +`; | ||
29 | + | ||
30 | +const Spacer = styled.div` | ||
31 | + height: 4rem; | ||
32 | +`; | ||
33 | +const UserInfo = styled.div` | ||
34 | + font-weight: 800; | ||
35 | + margin-right: 1rem; | ||
36 | +`; | ||
37 | + | ||
38 | +const Header = ({ user, onLogout }) => { | ||
39 | + return ( | ||
40 | + <> | ||
41 | + <HeaderBlock> | ||
42 | + <Wrapper> | ||
43 | + <Link to="/" className="logo"> | ||
44 | + 작심삼일 | ||
45 | + </Link> | ||
46 | + {user ? ( | ||
47 | + <div className="right"> | ||
48 | + <UserInfo>{user.username}</UserInfo> | ||
49 | + <Button onClick={onLogout}>로그아웃</Button> | ||
50 | + </div> | ||
51 | + ) : ( | ||
52 | + <div className="right"> | ||
53 | + <Button to="/login">로그인</Button> | ||
54 | + </div> | ||
55 | + )} | ||
56 | + </Wrapper> | ||
57 | + </HeaderBlock> | ||
58 | + <Spacer /> | ||
59 | + </> | ||
60 | + ); | ||
61 | +}; | ||
62 | + | ||
63 | +export default Header; |
1 | +import React from 'react'; | ||
2 | +import styled from 'styled-components'; | ||
3 | + | ||
4 | +const ResponsiveBlock = styled.div` | ||
5 | + padding-left: 1rem; | ||
6 | + padding-right: 1rem; | ||
7 | + width: 1024px; | ||
8 | + margin: 0 auto; | ||
9 | + | ||
10 | + @media (max-width: 1024px) { | ||
11 | + width: 768px; | ||
12 | + } | ||
13 | + @media (max-width: 768px) { | ||
14 | + width: 100%; | ||
15 | + } | ||
16 | +`; | ||
17 | + | ||
18 | +const Responsive = ({ children, ...rest }) => { | ||
19 | + return <ResponsiveBlock {...rest}>{children}</ResponsiveBlock>; | ||
20 | +}; | ||
21 | + | ||
22 | +export default Responsive; |
... | @@ -2,7 +2,8 @@ import React, { useEffect, useState } from 'react'; | ... | @@ -2,7 +2,8 @@ import React, { useEffect, useState } from 'react'; |
2 | import { useDispatch, useSelector } from 'react-redux'; | 2 | import { useDispatch, useSelector } from 'react-redux'; |
3 | import { withRouter } from 'react-router-dom'; | 3 | import { withRouter } from 'react-router-dom'; |
4 | import { changeField, initializeForm, login } from '../../modules/auth'; | 4 | import { changeField, initializeForm, login } from '../../modules/auth'; |
5 | -import AuthForm from './AuthForm'; | 5 | +import AuthForm from '../../components/auth/AuthForm'; |
6 | +import { check } from '../../modules/user'; | ||
6 | 7 | ||
7 | const LoginForm = ({ history }) => { | 8 | const LoginForm = ({ history }) => { |
8 | const dispatch = useDispatch(); | 9 | const dispatch = useDispatch(); |
... | @@ -59,8 +60,15 @@ const LoginForm = ({ history }) => { | ... | @@ -59,8 +60,15 @@ const LoginForm = ({ history }) => { |
59 | console.log(user); | 60 | console.log(user); |
60 | } | 61 | } |
61 | }, [history, user]); | 62 | }, [history, user]); |
62 | - | 63 | + return ( |
63 | - return <AuthForm type="login"></AuthForm>; | 64 | + <AuthForm |
65 | + type="login" | ||
66 | + form={form} | ||
67 | + onChange={onChange} | ||
68 | + onSubmit={onSubmit} | ||
69 | + error={error} | ||
70 | + ></AuthForm> | ||
71 | + ); | ||
64 | }; | 72 | }; |
65 | 73 | ||
66 | export default withRouter(LoginForm); | 74 | export default withRouter(LoginForm); | ... | ... |
1 | import React, { useEffect, useState } from 'react'; | 1 | import React, { useEffect, useState } from 'react'; |
2 | import { useDispatch, useSelector } from 'react-redux'; | 2 | import { useDispatch, useSelector } from 'react-redux'; |
3 | +import { changeField, initializeForm, register } from '../../modules/auth'; | ||
3 | import AuthForm from '../../components/auth/AuthForm'; | 4 | import AuthForm from '../../components/auth/AuthForm'; |
5 | +import { check } from '../../modules/user'; | ||
4 | import { withRouter } from 'react-router-dom'; | 6 | import { withRouter } from 'react-router-dom'; |
5 | 7 | ||
6 | const RegisterForm = ({ history }) => { | 8 | const RegisterForm = ({ history }) => { |
... | @@ -32,7 +34,6 @@ const RegisterForm = ({ history }) => { | ... | @@ -32,7 +34,6 @@ const RegisterForm = ({ history }) => { |
32 | return; | 34 | return; |
33 | } | 35 | } |
34 | if (password !== passwordConfirm) { | 36 | if (password !== passwordConfirm) { |
35 | - //Todo Handle Error | ||
36 | setError('비밀번호가 일치하지 않습니다.'); | 37 | setError('비밀번호가 일치하지 않습니다.'); |
37 | changeField({ form: 'register', key: 'password', value: '' }); | 38 | changeField({ form: 'register', key: 'password', value: '' }); |
38 | changeField({ form: 'register', key: 'passwordConfirm', value: '' }); | 39 | changeField({ form: 'register', key: 'passwordConfirm', value: '' }); |
... | @@ -72,8 +73,15 @@ const RegisterForm = ({ history }) => { | ... | @@ -72,8 +73,15 @@ const RegisterForm = ({ history }) => { |
72 | } | 73 | } |
73 | } | 74 | } |
74 | }, [history, user]); | 75 | }, [history, user]); |
75 | - | 76 | + return ( |
76 | - return <AuthForm type="register" form={form}></AuthForm>; | 77 | + <AuthForm |
78 | + type="register" | ||
79 | + form={form} | ||
80 | + onChange={onChange} | ||
81 | + onSubmit={onSubmit} | ||
82 | + error={error} | ||
83 | + ></AuthForm> | ||
84 | + ); | ||
77 | }; | 85 | }; |
78 | 86 | ||
79 | export default withRouter(RegisterForm); | 87 | export default withRouter(RegisterForm); | ... | ... |
1 | +import React from 'react'; | ||
2 | +import { useSelector, useDispatch } from 'react-redux'; | ||
3 | +import Header from '../../components/common/Header'; | ||
4 | +import { logout } from '../../modules/user'; | ||
5 | +const HeaderContainer = () => { | ||
6 | + const { user } = useSelector(({ user }) => ({ user: user.user })); | ||
7 | + const dispatch = useDispatch(); | ||
8 | + const onLogout = () => { | ||
9 | + dispatch(logout()); | ||
10 | + }; | ||
11 | + return <Header user={user} onLogout={onLogout} />; | ||
12 | +}; | ||
13 | +export default HeaderContainer; |
... | @@ -5,11 +5,31 @@ import App from './App'; | ... | @@ -5,11 +5,31 @@ import App from './App'; |
5 | import * as serviceWorker from './serviceWorker'; | 5 | import * as serviceWorker from './serviceWorker'; |
6 | import { BrowserRouter } from 'react-router-dom'; | 6 | import { BrowserRouter } from 'react-router-dom'; |
7 | import { Provider } from 'react-redux'; | 7 | import { Provider } from 'react-redux'; |
8 | -import { createStore } from 'redux'; | 8 | +import { createStore, applyMiddleware } from 'redux'; |
9 | import { composeWithDevTools } from 'redux-devtools-extension'; | 9 | import { composeWithDevTools } from 'redux-devtools-extension'; |
10 | -import rootReducer from './modules'; | 10 | +import createSagaMiddleware from 'redux-saga'; |
11 | +import rootReducer, { rootSaga } from './modules'; | ||
12 | +import { tempSetUser, check } from './modules/user'; | ||
11 | 13 | ||
12 | -const store = createStore(rootReducer, composeWithDevTools()); | 14 | +const sagaMiddleware = createSagaMiddleware(); |
15 | +const store = createStore( | ||
16 | + rootReducer, | ||
17 | + composeWithDevTools(applyMiddleware(sagaMiddleware)), | ||
18 | +); | ||
19 | + | ||
20 | +function loadUser() { | ||
21 | + try { | ||
22 | + const user = localStorage.getItem('user'); | ||
23 | + if (!user) return; | ||
24 | + | ||
25 | + store.dispatch(tempSetUser(user)); | ||
26 | + store.dispatch(check()); | ||
27 | + } catch (e) { | ||
28 | + console.log('localStorage is not working'); | ||
29 | + } | ||
30 | +} | ||
31 | +sagaMiddleware.run(rootSaga); | ||
32 | +loadUser(); | ||
13 | 33 | ||
14 | ReactDOM.render( | 34 | ReactDOM.render( |
15 | <Provider store={store}> | 35 | <Provider store={store}> | ... | ... |
jaksimsamil-page/src/lib/api/auth.js
0 → 100644
1 | +import client from './client'; | ||
2 | + | ||
3 | +export const login = ({ username, password }) => | ||
4 | + client.post('api/auth/login', { username, password }); | ||
5 | + | ||
6 | +export const register = ({ username, password }) => | ||
7 | + client.post('api/auth/register', { username, password }); | ||
8 | + | ||
9 | +export const check = () => client.get('api/auth/check'); | ||
10 | + | ||
11 | +export const logout = () => client.post('/api/auth/logout'); |
jaksimsamil-page/src/lib/api/client.js
0 → 100644
1 | +import { call, put } from 'redux-saga/effects'; | ||
2 | +import { startLoading, finishLoading } from '../modules/loading'; | ||
3 | + | ||
4 | +export const createRequestActionTypes = (type) => { | ||
5 | + const SUCCESS = `${type}_SUCCESS`; | ||
6 | + const FAILURE = `${type}_FAILURE`; | ||
7 | + return [type, SUCCESS, FAILURE]; | ||
8 | +}; | ||
9 | + | ||
10 | +export default function createRequestSaga(type, request) { | ||
11 | + const SUCCESS = `${type}_SUCCESS`; | ||
12 | + const FAILURE = `${type}_FAILURE`; | ||
13 | + | ||
14 | + return function* (action) { | ||
15 | + yield put(startLoading(type)); | ||
16 | + try { | ||
17 | + const response = yield call(request, action.payload); | ||
18 | + yield put({ | ||
19 | + type: SUCCESS, | ||
20 | + payload: response.data, | ||
21 | + }); | ||
22 | + } catch (e) { | ||
23 | + yield put({ | ||
24 | + type: FAILURE, | ||
25 | + payload: e, | ||
26 | + error: true, | ||
27 | + }); | ||
28 | + } | ||
29 | + yield put(finishLoading(type)); | ||
30 | + }; | ||
31 | +} |
1 | import { createAction, handleActions } from 'redux-actions'; | 1 | import { createAction, handleActions } from 'redux-actions'; |
2 | import produce from 'immer'; | 2 | import produce from 'immer'; |
3 | - | 3 | +import { takeLatest } from 'redux-saga/effects'; |
4 | -const CHANGE_FIELD = 'auth/CHANGE_FIELD'; | 4 | +import createRequestSaga, { |
5 | + createRequestActionTypes, | ||
6 | +} from '../lib/createRequestSaga'; | ||
7 | +import * as authAPI from '../lib/api/auth'; | ||
8 | +const CHAGE_FIELD = 'auth/CHANGE_FIELD'; | ||
5 | const INITIALIZE_FORM = 'auth/INITIALIZE_FORM'; | 9 | const INITIALIZE_FORM = 'auth/INITIALIZE_FORM'; |
6 | 10 | ||
7 | -export const sampleAction = createAction(SAMPLE_ACTION); | 11 | +const REGISTER = 'auth/REGISTER'; |
8 | -export const cahngeField = createAction( | 12 | +const REGISTER_SUCCESS = 'auth/REGISTER_SUCCESS'; |
9 | - CHANGE_FIELD, | 13 | +const REGISTER_FAILURE = 'auth/REGISTER_FAILURE'; |
10 | - ({ form, key, value }) => { | 14 | + |
11 | - form, key, value; | 15 | +const LOGIN = 'auth/LOGIN'; |
12 | - }, | 16 | +const LOGIN_SUCCESS = 'auth/LOGIN_SUCCESS'; |
17 | +const LOGIN_FAILURE = 'auth/LOGIN_FAILURE'; | ||
18 | + | ||
19 | +export const changeField = createAction( | ||
20 | + CHAGE_FIELD, | ||
21 | + ({ form, key, value }) => ({ | ||
22 | + form, | ||
23 | + key, | ||
24 | + value, | ||
25 | + }), | ||
13 | ); | 26 | ); |
14 | export const initializeForm = createAction(INITIALIZE_FORM, (form) => form); | 27 | export const initializeForm = createAction(INITIALIZE_FORM, (form) => form); |
15 | 28 | ||
16 | -const initialState = { | 29 | +const initalState = { |
17 | register: { | 30 | register: { |
18 | username: '', | 31 | username: '', |
19 | password: '', | 32 | password: '', |
... | @@ -23,20 +36,58 @@ const initialState = { | ... | @@ -23,20 +36,58 @@ const initialState = { |
23 | username: '', | 36 | username: '', |
24 | password: '', | 37 | password: '', |
25 | }, | 38 | }, |
39 | + auth: null, | ||
40 | + authError: null, | ||
26 | }; | 41 | }; |
27 | 42 | ||
43 | +export const register = createAction(REGISTER, ({ username, password }) => ({ | ||
44 | + username, | ||
45 | + password, | ||
46 | +})); | ||
47 | +export const login = createAction(LOGIN, ({ username, password }) => ({ | ||
48 | + username, | ||
49 | + password, | ||
50 | +})); | ||
51 | + | ||
52 | +const registerSaga = createRequestSaga(REGISTER, authAPI.register); | ||
53 | +const loginSaga = createRequestSaga(LOGIN, authAPI.login); | ||
54 | + | ||
55 | +export function* authSaga() { | ||
56 | + yield takeLatest(REGISTER, registerSaga); | ||
57 | + yield takeLatest(LOGIN, loginSaga); | ||
58 | +} | ||
59 | + | ||
28 | const auth = handleActions( | 60 | const auth = handleActions( |
29 | { | 61 | { |
30 | - [CHANGE_FIELD]: (state, { payload: { form, key, value } }) => | 62 | + [CHAGE_FIELD]: (state, { payload: { form, key, value } }) => |
31 | produce(state, (draft) => { | 63 | produce(state, (draft) => { |
32 | draft[form][key] = value; | 64 | draft[form][key] = value; |
33 | }), | 65 | }), |
34 | [INITIALIZE_FORM]: (state, { payload: form }) => ({ | 66 | [INITIALIZE_FORM]: (state, { payload: form }) => ({ |
35 | ...state, | 67 | ...state, |
36 | - [form]: initialState[form], | 68 | + [form]: initalState[form], |
69 | + authError: null, | ||
70 | + }), | ||
71 | + [REGISTER_SUCCESS]: (state, { payload: auth }) => ({ | ||
72 | + ...state, | ||
73 | + authError: null, | ||
74 | + auth, | ||
75 | + }), | ||
76 | + [REGISTER_FAILURE]: (state, { payload: error }) => ({ | ||
77 | + ...state, | ||
78 | + authError: error, | ||
79 | + }), | ||
80 | + [LOGIN_SUCCESS]: (state, { payload: auth }) => ({ | ||
81 | + ...state, | ||
82 | + authError: null, | ||
83 | + auth, | ||
84 | + }), | ||
85 | + [LOGIN_FAILURE]: (state, { payload: error }) => ({ | ||
86 | + ...state, | ||
87 | + authError: error, | ||
37 | }), | 88 | }), |
38 | }, | 89 | }, |
39 | - initialState, | 90 | + initalState, |
40 | ); | 91 | ); |
41 | 92 | ||
42 | export default auth; | 93 | export default auth; | ... | ... |
1 | import { combineReducers } from 'redux'; | 1 | import { combineReducers } from 'redux'; |
2 | -import auth from './auth'; | 2 | +import { all } from 'redux-saga/effects'; |
3 | +import auth, { authSaga } from './auth'; | ||
4 | +import loading from './loading'; | ||
5 | +import user, { userSaga } from './user'; | ||
3 | 6 | ||
4 | const rootReducer = combineReducers({ | 7 | const rootReducer = combineReducers({ |
5 | auth, | 8 | auth, |
9 | + loading, | ||
10 | + user, | ||
6 | }); | 11 | }); |
7 | 12 | ||
13 | +export function* rootSaga() { | ||
14 | + yield all([authSaga(), userSaga()]); | ||
15 | +} | ||
16 | + | ||
8 | export default rootReducer; | 17 | export default rootReducer; | ... | ... |
jaksimsamil-page/src/modules/loading.js
0 → 100644
1 | +import { createAction, handleActions } from 'redux-actions'; | ||
2 | + | ||
3 | +const START_LOADING = 'loading/START_LOADING'; | ||
4 | +const FINISH_LOADING = 'loading/FINISH_LOADING'; | ||
5 | + | ||
6 | +export const startLoading = createAction( | ||
7 | + START_LOADING, | ||
8 | + (requestType) => requestType, | ||
9 | +); | ||
10 | + | ||
11 | +export const finishLoading = createAction( | ||
12 | + FINISH_LOADING, | ||
13 | + (requestType) => requestType, | ||
14 | +); | ||
15 | + | ||
16 | +const initialState = {}; | ||
17 | + | ||
18 | +const loading = handleActions( | ||
19 | + { | ||
20 | + [START_LOADING]: (state, action) => ({ | ||
21 | + ...state, | ||
22 | + [action.payload]: true, | ||
23 | + }), | ||
24 | + [FINISH_LOADING]: (state, action) => ({ | ||
25 | + ...state, | ||
26 | + [action.payload]: false, | ||
27 | + }), | ||
28 | + }, | ||
29 | + initialState, | ||
30 | +); | ||
31 | + | ||
32 | +export default loading; |
jaksimsamil-page/src/modules/user.js
0 → 100644
1 | +import { createAction, handleActions } from 'redux-actions'; | ||
2 | +import { takeLatest, call } from 'redux-saga/effects'; | ||
3 | +import * as authAPI from '../lib/api/auth'; | ||
4 | +import createRequestSaga, { | ||
5 | + createRequestActionTypes, | ||
6 | +} from '../lib/createRequestSaga'; | ||
7 | + | ||
8 | +const TEMP_SET_USER = 'user/TEMP_SET_USER'; | ||
9 | +const [CHECK, CHECK_SUCCESS, CHECK_FAILURE] = createRequestActionTypes( | ||
10 | + 'user/CHECK', | ||
11 | +); | ||
12 | +const LOGOUT = 'user/LOGOUT'; | ||
13 | + | ||
14 | +export const tempSetUser = createAction(TEMP_SET_USER, (user) => user); | ||
15 | +export const check = createAction(CHECK); | ||
16 | +export const logout = createAction(LOGOUT); | ||
17 | +const checkSaga = createRequestSaga(CHECK, authAPI.check); | ||
18 | +function checkFailureSaga() { | ||
19 | + try { | ||
20 | + localStorage.removeItem('user'); | ||
21 | + } catch (e) { | ||
22 | + console.log('localStroage is not working'); | ||
23 | + } | ||
24 | +} | ||
25 | +function* logoutSaga() { | ||
26 | + try { | ||
27 | + yield call(authAPI.logout); | ||
28 | + console.log('logout'); | ||
29 | + localStorage.removeItem('user'); | ||
30 | + } catch (e) { | ||
31 | + console.log(e); | ||
32 | + } | ||
33 | +} | ||
34 | +export function* userSaga() { | ||
35 | + yield takeLatest(CHECK, checkSaga); | ||
36 | + yield takeLatest(CHECK_FAILURE, checkFailureSaga); | ||
37 | + yield takeLatest(LOGOUT, logoutSaga); | ||
38 | +} | ||
39 | + | ||
40 | +const initialState = { | ||
41 | + user: null, | ||
42 | + checkError: null, | ||
43 | +}; | ||
44 | + | ||
45 | +export default handleActions( | ||
46 | + { | ||
47 | + [TEMP_SET_USER]: (state, { payload: user }) => ({ | ||
48 | + ...state, | ||
49 | + user, | ||
50 | + }), | ||
51 | + [CHECK_SUCCESS]: (state, { payload: user }) => ({ | ||
52 | + ...state, | ||
53 | + user, | ||
54 | + checkError: null, | ||
55 | + }), | ||
56 | + [CHECK_FAILURE]: (state, { payload: error }) => ({ | ||
57 | + ...state, | ||
58 | + user: null, | ||
59 | + checkError: error, | ||
60 | + }), | ||
61 | + [LOGOUT]: (state) => ({ | ||
62 | + ...state, | ||
63 | + user: null, | ||
64 | + }), | ||
65 | + }, | ||
66 | + initialState, | ||
67 | +); |
1 | import React from 'react'; | 1 | import React from 'react'; |
2 | +import HeaderContainer from '../containers/common/HeaderContainer'; | ||
2 | import Button from '../components/common/Button'; | 3 | import Button from '../components/common/Button'; |
3 | 4 | ||
4 | const HomePage = () => { | 5 | const HomePage = () => { |
5 | return ( | 6 | return ( |
6 | <div> | 7 | <div> |
8 | + <HeaderContainer /> | ||
7 | <Button>test</Button> | 9 | <Button>test</Button> |
8 | </div> | 10 | </div> |
9 | ); | 11 | ); | ... | ... |
... | @@ -1026,6 +1026,13 @@ | ... | @@ -1026,6 +1026,13 @@ |
1026 | dependencies: | 1026 | dependencies: |
1027 | regenerator-runtime "^0.13.4" | 1027 | regenerator-runtime "^0.13.4" |
1028 | 1028 | ||
1029 | +"@babel/runtime@^7.6.3": | ||
1030 | + version "7.10.2" | ||
1031 | + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.2.tgz#d103f21f2602497d38348a32e008637d506db839" | ||
1032 | + integrity sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg== | ||
1033 | + dependencies: | ||
1034 | + regenerator-runtime "^0.13.4" | ||
1035 | + | ||
1029 | "@babel/template@^7.10.1": | 1036 | "@babel/template@^7.10.1": |
1030 | version "7.10.1" | 1037 | version "7.10.1" |
1031 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.1.tgz#e167154a94cb5f14b28dc58f5356d2162f539811" | 1038 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.1.tgz#e167154a94cb5f14b28dc58f5356d2162f539811" |
... | @@ -1344,6 +1351,50 @@ | ... | @@ -1344,6 +1351,50 @@ |
1344 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" | 1351 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" |
1345 | integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== | 1352 | integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== |
1346 | 1353 | ||
1354 | +"@redux-saga/core@^1.1.3": | ||
1355 | + version "1.1.3" | ||
1356 | + resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.1.3.tgz#3085097b57a4ea8db5528d58673f20ce0950f6a4" | ||
1357 | + integrity sha512-8tInBftak8TPzE6X13ABmEtRJGjtK17w7VUs7qV17S8hCO5S3+aUTWZ/DBsBJPdE8Z5jOPwYALyvofgq1Ws+kg== | ||
1358 | + dependencies: | ||
1359 | + "@babel/runtime" "^7.6.3" | ||
1360 | + "@redux-saga/deferred" "^1.1.2" | ||
1361 | + "@redux-saga/delay-p" "^1.1.2" | ||
1362 | + "@redux-saga/is" "^1.1.2" | ||
1363 | + "@redux-saga/symbols" "^1.1.2" | ||
1364 | + "@redux-saga/types" "^1.1.0" | ||
1365 | + redux "^4.0.4" | ||
1366 | + typescript-tuple "^2.2.1" | ||
1367 | + | ||
1368 | +"@redux-saga/deferred@^1.1.2": | ||
1369 | + version "1.1.2" | ||
1370 | + resolved "https://registry.yarnpkg.com/@redux-saga/deferred/-/deferred-1.1.2.tgz#59937a0eba71fff289f1310233bc518117a71888" | ||
1371 | + integrity sha512-908rDLHFN2UUzt2jb4uOzj6afpjgJe3MjICaUNO3bvkV/kN/cNeI9PMr8BsFXB/MR8WTAZQq/PlTq8Kww3TBSQ== | ||
1372 | + | ||
1373 | +"@redux-saga/delay-p@^1.1.2": | ||
1374 | + version "1.1.2" | ||
1375 | + resolved "https://registry.yarnpkg.com/@redux-saga/delay-p/-/delay-p-1.1.2.tgz#8f515f4b009b05b02a37a7c3d0ca9ddc157bb355" | ||
1376 | + integrity sha512-ojc+1IoC6OP65Ts5+ZHbEYdrohmIw1j9P7HS9MOJezqMYtCDgpkoqB5enAAZrNtnbSL6gVCWPHaoaTY5KeO0/g== | ||
1377 | + dependencies: | ||
1378 | + "@redux-saga/symbols" "^1.1.2" | ||
1379 | + | ||
1380 | +"@redux-saga/is@^1.1.2": | ||
1381 | + version "1.1.2" | ||
1382 | + resolved "https://registry.yarnpkg.com/@redux-saga/is/-/is-1.1.2.tgz#ae6c8421f58fcba80faf7cadb7d65b303b97e58e" | ||
1383 | + integrity sha512-OLbunKVsCVNTKEf2cH4TYyNbbPgvmZ52iaxBD4I1fTif4+MTXMa4/Z07L83zW/hTCXwpSZvXogqMqLfex2Tg6w== | ||
1384 | + dependencies: | ||
1385 | + "@redux-saga/symbols" "^1.1.2" | ||
1386 | + "@redux-saga/types" "^1.1.0" | ||
1387 | + | ||
1388 | +"@redux-saga/symbols@^1.1.2": | ||
1389 | + version "1.1.2" | ||
1390 | + resolved "https://registry.yarnpkg.com/@redux-saga/symbols/-/symbols-1.1.2.tgz#216a672a487fc256872b8034835afc22a2d0595d" | ||
1391 | + integrity sha512-EfdGnF423glv3uMwLsGAtE6bg+R9MdqlHEzExnfagXPrIiuxwr3bdiAwz3gi+PsrQ3yBlaBpfGLtDG8rf3LgQQ== | ||
1392 | + | ||
1393 | +"@redux-saga/types@^1.1.0": | ||
1394 | + version "1.1.0" | ||
1395 | + resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204" | ||
1396 | + integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg== | ||
1397 | + | ||
1347 | "@sheerun/mutationobserver-shim@^0.3.2": | 1398 | "@sheerun/mutationobserver-shim@^0.3.2": |
1348 | version "0.3.3" | 1399 | version "0.3.3" |
1349 | resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25" | 1400 | resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25" |
... | @@ -2312,6 +2363,13 @@ aws4@^1.8.0: | ... | @@ -2312,6 +2363,13 @@ aws4@^1.8.0: |
2312 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" | 2363 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" |
2313 | integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== | 2364 | integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== |
2314 | 2365 | ||
2366 | +axios@^0.19.2: | ||
2367 | + version "0.19.2" | ||
2368 | + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" | ||
2369 | + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== | ||
2370 | + dependencies: | ||
2371 | + follow-redirects "1.5.10" | ||
2372 | + | ||
2315 | axobject-query@^2.0.2: | 2373 | axobject-query@^2.0.2: |
2316 | version "2.1.2" | 2374 | version "2.1.2" |
2317 | resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799" | 2375 | resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799" |
... | @@ -3852,7 +3910,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: | ... | @@ -3852,7 +3910,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: |
3852 | dependencies: | 3910 | dependencies: |
3853 | ms "2.0.0" | 3911 | ms "2.0.0" |
3854 | 3912 | ||
3855 | -debug@3.1.0: | 3913 | +debug@3.1.0, debug@=3.1.0: |
3856 | version "3.1.0" | 3914 | version "3.1.0" |
3857 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" | 3915 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" |
3858 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== | 3916 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== |
... | @@ -5023,6 +5081,13 @@ flush-write-stream@^1.0.0: | ... | @@ -5023,6 +5081,13 @@ flush-write-stream@^1.0.0: |
5023 | inherits "^2.0.3" | 5081 | inherits "^2.0.3" |
5024 | readable-stream "^2.3.6" | 5082 | readable-stream "^2.3.6" |
5025 | 5083 | ||
5084 | +follow-redirects@1.5.10: | ||
5085 | + version "1.5.10" | ||
5086 | + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" | ||
5087 | + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== | ||
5088 | + dependencies: | ||
5089 | + debug "=3.1.0" | ||
5090 | + | ||
5026 | follow-redirects@^1.0.0: | 5091 | follow-redirects@^1.0.0: |
5027 | version "1.10.0" | 5092 | version "1.10.0" |
5028 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.10.0.tgz#01f5263aee921c6a54fb91667f08f4155ce169eb" | 5093 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.10.0.tgz#01f5263aee921c6a54fb91667f08f4155ce169eb" |
... | @@ -10295,7 +10360,14 @@ redux-devtools-extension@^2.13.8: | ... | @@ -10295,7 +10360,14 @@ redux-devtools-extension@^2.13.8: |
10295 | resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz#37b982688626e5e4993ff87220c9bbb7cd2d96e1" | 10360 | resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz#37b982688626e5e4993ff87220c9bbb7cd2d96e1" |
10296 | integrity sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg== | 10361 | integrity sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg== |
10297 | 10362 | ||
10298 | -redux@^4.0.5: | 10363 | +redux-saga@^1.1.3: |
10364 | + version "1.1.3" | ||
10365 | + resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.1.3.tgz#9f3e6aebd3c994bbc0f6901a625f9a42b51d1112" | ||
10366 | + integrity sha512-RkSn/z0mwaSa5/xH/hQLo8gNf4tlvT18qXDNvedihLcfzh+jMchDgaariQoehCpgRltEm4zHKJyINEz6aqswTw== | ||
10367 | + dependencies: | ||
10368 | + "@redux-saga/core" "^1.1.3" | ||
10369 | + | ||
10370 | +redux@^4.0.4, redux@^4.0.5: | ||
10299 | version "4.0.5" | 10371 | version "4.0.5" |
10300 | resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" | 10372 | resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" |
10301 | integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== | 10373 | integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== |
... | @@ -11866,6 +11938,25 @@ typedarray@^0.0.6: | ... | @@ -11866,6 +11938,25 @@ typedarray@^0.0.6: |
11866 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" | 11938 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" |
11867 | integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= | 11939 | integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= |
11868 | 11940 | ||
11941 | +typescript-compare@^0.0.2: | ||
11942 | + version "0.0.2" | ||
11943 | + resolved "https://registry.yarnpkg.com/typescript-compare/-/typescript-compare-0.0.2.tgz#7ee40a400a406c2ea0a7e551efd3309021d5f425" | ||
11944 | + integrity sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA== | ||
11945 | + dependencies: | ||
11946 | + typescript-logic "^0.0.0" | ||
11947 | + | ||
11948 | +typescript-logic@^0.0.0: | ||
11949 | + version "0.0.0" | ||
11950 | + resolved "https://registry.yarnpkg.com/typescript-logic/-/typescript-logic-0.0.0.tgz#66ebd82a2548f2b444a43667bec120b496890196" | ||
11951 | + integrity sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q== | ||
11952 | + | ||
11953 | +typescript-tuple@^2.2.1: | ||
11954 | + version "2.2.1" | ||
11955 | + resolved "https://registry.yarnpkg.com/typescript-tuple/-/typescript-tuple-2.2.1.tgz#7d9813fb4b355f69ac55032e0363e8bb0f04dad2" | ||
11956 | + integrity sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q== | ||
11957 | + dependencies: | ||
11958 | + typescript-compare "^0.0.2" | ||
11959 | + | ||
11869 | uid-number@0.0.6: | 11960 | uid-number@0.0.6: |
11870 | version "0.0.6" | 11961 | version "0.0.6" |
11871 | resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" | 11962 | resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" | ... | ... |
... | @@ -32,6 +32,6 @@ | ... | @@ -32,6 +32,6 @@ |
32 | | profile | 추천 문제 조회 | GET | api/profile/recommend:id | 바로가기 | None | | 32 | | profile | 추천 문제 조회 | GET | api/profile/recommend:id | 바로가기 | None | |
33 | | notify | 슬랙 메시지 전송 요청 | POST | api/notify/slack | 바로가기 | Jwt Token | | 33 | | notify | 슬랙 메시지 전송 요청 | POST | api/notify/slack | 바로가기 | Jwt Token | |
34 | | auth | 로그인 | POST | api/auth/login | 바로가기 | None | | 34 | | auth | 로그인 | POST | api/auth/login | 바로가기 | None | |
35 | -| auth | 로그아웃 | GET | api/auth/logout | 바로가기 | JWT Token | | 35 | +| auth | 로그아웃 | POST | api/auth/logout | 바로가기 | JWT Token | |
36 | | auth | 회원가입 | POST | api/auth/register | 바로가기 | None | | 36 | | auth | 회원가입 | POST | api/auth/register | 바로가기 | None | |
37 | | auth | 로그인 확인 | GET | api/auth/check | 바로가기 | None | | 37 | | auth | 로그인 확인 | GET | api/auth/check | 바로가기 | None | | ... | ... |
... | @@ -40,7 +40,7 @@ exports.register = async (ctx) => { | ... | @@ -40,7 +40,7 @@ exports.register = async (ctx) => { |
40 | ctx.body = user.serialize(); | 40 | ctx.body = user.serialize(); |
41 | 41 | ||
42 | const token = user.generateToken(); | 42 | const token = user.generateToken(); |
43 | - ctx.cookies.set("acces_token", token, { | 43 | + ctx.cookies.set("access_token", token, { |
44 | //3일동안 유효 | 44 | //3일동안 유효 |
45 | maxAge: 1000 * 60 * 60 * 24 * 3, | 45 | maxAge: 1000 * 60 * 60 * 24 * 3, |
46 | httpOnly: true, | 46 | httpOnly: true, |
... | @@ -75,7 +75,7 @@ exports.login = async (ctx) => { | ... | @@ -75,7 +75,7 @@ exports.login = async (ctx) => { |
75 | } | 75 | } |
76 | ctx.body = user.serialize(); | 76 | ctx.body = user.serialize(); |
77 | const token = user.generateToken(); | 77 | const token = user.generateToken(); |
78 | - ctx.cookies.set("acces_token", token, { | 78 | + ctx.cookies.set("access_token", token, { |
79 | //7일동안 유효 | 79 | //7일동안 유효 |
80 | maxAge: 1000 * 60 * 60 * 24 * 7, | 80 | maxAge: 1000 * 60 * 60 * 24 * 7, |
81 | httpOnly: true, | 81 | httpOnly: true, |
... | @@ -88,6 +88,7 @@ exports.login = async (ctx) => { | ... | @@ -88,6 +88,7 @@ exports.login = async (ctx) => { |
88 | GET api/auth/check | 88 | GET api/auth/check |
89 | */ | 89 | */ |
90 | exports.check = async (ctx) => { | 90 | exports.check = async (ctx) => { |
91 | + console.log(ctx.state); | ||
91 | const { user } = ctx.state; | 92 | const { user } = ctx.state; |
92 | if (!user) { | 93 | if (!user) { |
93 | ctx.status = 401; | 94 | ctx.status = 401; | ... | ... |
... | @@ -2,7 +2,8 @@ const Router = require("koa-router"); | ... | @@ -2,7 +2,8 @@ const Router = require("koa-router"); |
2 | const auth = new Router(); | 2 | const auth = new Router(); |
3 | const authCtrl = require("./auth.ctrl"); | 3 | const authCtrl = require("./auth.ctrl"); |
4 | auth.post("/login", authCtrl.login); | 4 | auth.post("/login", authCtrl.login); |
5 | -auth.get("/logout", authCtrl.logout); | 5 | +auth.post("/logout", authCtrl.logout); |
6 | auth.post("/register", authCtrl.register); | 6 | auth.post("/register", authCtrl.register); |
7 | +auth.get("/check", authCtrl.check); | ||
7 | 8 | ||
8 | module.exports = auth; | 9 | module.exports = auth; | ... | ... |
1 | const jwt = require("jsonwebtoken"); | 1 | const jwt = require("jsonwebtoken"); |
2 | const User = require("../models/user"); | 2 | const User = require("../models/user"); |
3 | + | ||
3 | const jwtMiddleware = async (ctx, next) => { | 4 | const jwtMiddleware = async (ctx, next) => { |
4 | const token = ctx.cookies.get("access_token"); | 5 | const token = ctx.cookies.get("access_token"); |
6 | + console.log("1"); | ||
7 | + console.log(token); | ||
5 | if (!token) { | 8 | if (!token) { |
6 | - //토큰이 없을 때 | 9 | + console.log("1"); |
7 | return next(); | 10 | return next(); |
8 | } | 11 | } |
9 | try { | 12 | try { |
10 | - const decoded = jwt.verify(token, process.env.JWT_TOKEN); | 13 | + console.log("1"); |
14 | + const decoded = jwt.verify(token, process.env.JWT_SECRET); | ||
11 | ctx.state.user = { | 15 | ctx.state.user = { |
12 | _id: decoded._id, | 16 | _id: decoded._id, |
13 | username: decoded.username, | 17 | username: decoded.username, |
14 | }; | 18 | }; |
15 | - //토큰의 남은 유효 기간이 2일 이하라면 재발급 | 19 | + const now = Math.floor(Date.now() / 1000); |
16 | - if (decoded.exp - Date.now() / 1000 < 60 * 60 * 24 * 2) { | 20 | + if (decoded.exp - now < 60 * 60 * 24 * 3.5) { |
17 | const user = await User.findById(decoded._id); | 21 | const user = await User.findById(decoded._id); |
18 | const token = user.generateToken(); | 22 | const token = user.generateToken(); |
19 | ctx.cookies.set("access_token", token, { | 23 | ctx.cookies.set("access_token", token, { |
20 | - maxAge: 1000 * 60 * 60 * 24 * 7, | 24 | + maxAge: 1000 * 60 * 60 * 24 * 7, //7days |
21 | httpOnly: true, | 25 | httpOnly: true, |
22 | }); | 26 | }); |
23 | } | 27 | } |
28 | + console.log(decoded); | ||
24 | return next(); | 29 | return next(); |
25 | } catch (e) { | 30 | } catch (e) { |
26 | return next(); | 31 | return next(); |
27 | } | 32 | } |
28 | }; | 33 | }; |
29 | - | ||
30 | module.exports = jwtMiddleware; | 34 | module.exports = jwtMiddleware; | ... | ... |
-
Please register or login to post a comment