server/auth.js 생성
client/src/auth.js 생성
client/src/components/HomePage.js 생성
const {User} = require('./models/User')
//인증 처리
let auth = (req, res, next) => {
//1 클라이언트에서 토큰을 가져옴
let token = req.cookies.x_auth
//2 토큰을 복호화하고 유저를 찾음
User.findByToken(token, (err, user) => {
if(err) throw err
if(!user) return res.json({ isAuth: false, error: true })
req.token = token
req.user = user
next()
})
//3 유저가 있으면 인증, 없으면 인증안함
}
module.exports = { auth };
import React, {useEffect} from 'react';
import {useSelector, useDispatch} from 'react-redux';
import {auth} from './_actions/user_action'
export default function (SpecificComponent, option, adminRoute = null) {
//null => 아무나 출입이 가능한 페이지
//true => 로그인한 유저만 출입이 가능한 페이지
//false=> 로그인한 유저는 출입 불가능한 페이지
function AuthenticationCheck(props){
let user = useSelector(state => state.user);
const dispatch = useDispatch();
useEffect(() => {
dispatch(auth()).then(response => {
if(!response.payload.isAuth){
if(option) {
props.history.push('/sign_in')
}
} else {
if(adminRoute && !response.payload.isAdmin) {
props.history.push('/home')
} else {
if(option === false)
props.history.push('/home')
}
}
})
}, [])
return (
<SpecificComponent {...props} user={user} />
)
}
return AuthenticationCheck
}
import React from 'react';
import {withRouter} from 'react-router-dom'
function HomePage() {
return (
<div>
<h2>환영합니다.</h2>
</div>
);
}
export default withRouter(HomePage)
import axios from 'axios';
import React, {useState} from 'react';
import {withRouter} from 'react-router-dom'
import {Link} from "react-router-dom";
import {useSelector} from "react-redux";
import "./Navbar.css"
const Navbar = (props) => {
const [sign, setSign] = useState(true)
const onClick = () => {
setSign((prev) => !prev)
}
const user = useSelector(state => state.user)
const onClickLogout = () => {
axios.get('/api/users/logout')
.then(response => {
if(response.data.success) {
props.history.push("/sign_in")
} else {
alert("Failed to logout")
}
})
}
if (user.userData && !user.userData.isAuth) {
return (
<div>
<nav>
<ul className="navbar">
<li><Link to="/">LOGO</Link></li>
{sign ? (
<li><Link to="/sign_in"><button onClick={onClick}>로그인</button></Link></li>
) : (
<li><Link to="/sign_up"><button onClick={onClick}>회원가입</button></Link></li>
)}
</ul>
</nav>
</div>
)
} else {
return (
<div>
<nav>
<ul className="navbar">
<li><Link to="/home">LOGO</Link></li>
<li><button onClick={onClickLogout}>로그아웃</button></li>
</ul>
</nav>
</div>
)
}
};
export default withRouter(Navbar)
import React from "react";
import {BrowserRouter as Router, Switch, Route} from "react-router-dom";
import Navbar from './components/Navbar';
import LandingPage from './components/LandingPage';
import LoginPage from './components/LoginPage';
import RegisterPage from './components/RegisterPage';
import HomePage from './components/HomePage';
import Auth from './auth'
function App() {
return (
<Router>
<div>
<Navbar />
<Switch>
<Route exact path="/" component={Auth(LandingPage, false)} />
<Route exact path="/sign_in" component={Auth(LoginPage, false)} />
<Route exact path="/sign_up" component={Auth(RegisterPage, false)} />
<Route exact path="/home" component={Auth(HomePage, true)} />
</Switch>
</div>
</Router>
);
}
export default App;
//인증
const { auth } = require("./auth")
app.get('/api/users/auth', auth, (req, res) => {
res.status(200).json({
_id: req.user._id,
isAdmin: req.user.role === 0 ? false : true,
isAuth: true,
email: req.user.email,
name: req.user.name,
lastname: req.user.lastname,
role: req.user.role,
image: req.user.image
})
})
//인증 시 토큰과 디비의 토큰을 복호화하여 비교
userSchema.statics.findByToken = function(token, cb) {
var user = this;
jwt.verify(token, 'secretToken', function(err, decoded) {
user.findOne({"_id": decoded, "token": token}, function(err, user) {
if(err) return cb(err)
cb(null, user)
})
})
}