정승호

로그인 페이지 제작

This diff is collapsed. Click to expand it.
......@@ -6,9 +6,17 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"antd": "^4.3.4",
"axios": "^0.19.2",
"http-proxy-middleware": "^1.0.4",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1"
"react-redux": "^7.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"redux": "^4.0.5",
"redux-promise": "^0.6.0",
"redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
......
import React from 'react';
import logo from './logo.svg';
import './App.css';
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import LandingPage from './components/views/LandingPage/LandingPage';
import LoginPage from './components/views/LoginPage/LoginPage';
import RegisterPage from './components/views/RegisterPage/RegisterPage';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<Router>
<div>
{/*
A <Switch> looks through all its children <Route>
elements and renders the first one whose path
matches the current URL. Use a <Switch> any time
you have multiple routes, but you want only one
of them to render at a time
*/}
<Switch>
<Route exact path="/" component={LandingPage}/>
<Route exact path="/login" component={LoginPage}/>
<Route exact path="/register" component = {RegisterPage} />
</Switch>
</div>
</Router>
);
}
export default App;
export default App
......
export const LOGIN_USER = "login_user";
\ No newline at end of file
import axios from 'axios';
import {
LOGIN_USER
} from './types';
export function loginUser(dataTosubmit){
const request = axios.post('/api/users/login', dataTosubmit)
.then(response => response.data)
return {
type: LOGIN_USER,
payload: request
}
}
\ No newline at end of file
import {combineReducers} from 'redux';
import user from './user_reducer';
const rootReducer = combineReducers({
user
})
export default rootReducer
\ No newline at end of file
import {
LOGIN_USER
} from '../_actions/types';
export default function (state={}, action){
switch (action.type) {
case LOGIN_USER:
return { ...state, loginSuccess: action.payload}
break;
default:
return state;
}
}
\ No newline at end of file
import React from 'react'
import React, {useEffect} from 'react'
import axios from 'axios';
function LandingPage(){
return(
<div>
function LandingPage() {
useEffect(() => {
axios.get('/api/hello')
.then(response => {console.log(response)})
}, [])
</div>
return (
<div style = {{
display: 'flex', justifyContent: 'center', alignItems: 'center'
, width: '100%', height: '100vh'
}}>
<h2> 시작 페이지 </h2>
</div>
)
}
......
import React from 'react'
import React,{useState} from 'react'
import Axios from 'axios'
import { useDispatch} from 'react-redux';
import {loginUser} from '../../../_actions/user_actions';
function LoginPage(){
const dispatch = useDispatch();
const [Email, setEmail] = useState("")
const [PassWord, setPassWord] = useState("")
const onEmailHandler = (event) => {
setEmail(event.currentTarget.value)
}
const onPassWordHandler = (event) => {
setPassWord(event.currentTarget.value)
}
const onSubmitHandler = (event) => {
event.preventDefault();
let body = {
email: Email,
password: PassWord
}
dispatch(loginUser(body))
}
return (
<div>
LoginPage
<div style = {{
display: 'flex', justifyContent: 'center', alignItems: 'center'
, width: '100%', height: '100vh'
}}>
<form style = {{display :'flex', flexDirection: 'column'}}
onSubmit= {onSubmitHandler}
>
<label>Email</label>
<input type = "email" value = {Email} onChange={onEmailHandler} />
<label>PassWord</label>
<input type = "password" value= {PassWord} onChange = {onPassWordHandler} />
<br />
<button type = "submit">
Login
</button>
</form>
</div>
)
......
......@@ -3,12 +3,30 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {Provider} from 'react-redux';
import 'antd/dist/antd.css';
import { applyMiddleware, createStore} from 'redux';
import promiseMiddleware from 'redux-promise';
import ReduxThunk from 'redux-thunk';
import Reducer from './_reducers/index';
const creatStoreWithMiddleware = applyMiddleware(promiseMiddleware,ReduxThunk)(createStore)
ReactDOM.render(
<React.StrictMode>
<Provider
store={creatStoreWithMiddleware(Reducer,
window.__REDUX_DEVTOOLS_EXTENTION__&&
window.__REDUX_DEVTOOLS_EXTENTION__()
)}
>
<App />
</React.StrictMode>,
document.getElementById('root')
</Provider>
,document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
......
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function(app){
app.use(
createProxyMiddleware('/api',{
target : 'http://localhost:5000/',
changeOrigin: true
})
)
};
This diff is collapsed. Click to expand it.
......@@ -5,8 +5,9 @@
"main": "index.js",
"scripts": {
"start": "node index.js",
"backend": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
"backend": "nodemon server/index.js",
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "concurrently \"npm run backend \" \"npm run start --prefix client\""
},
"repository": {
"type": "git",
......@@ -17,6 +18,7 @@
"dependencies": {
"bcrypt": "^4.0.1",
"body-parser": "^1.19.0",
"concurrently": "^5.2.0",
"cookie-parser": "^1.4.5",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
......
......@@ -22,7 +22,7 @@ mongoose.connect(config.mongoURI,{
app.get('/', (req,res) => res.send('Hello world!! 오늘도 지식이 쌓였당!!'))
app.get('/api/hello', (req,res) => res.send('Hello world!! 오늘도 지식이 쌓였당!!'))
app.post('/api/users/register', (req, res) => {
// 회원 가입시 필요한 정보들을 client에서 가져오면
......
......@@ -23,4 +23,4 @@ let auth = (req,res,next) => {
}
module.exports = {auth};
\ No newline at end of file
module.exports = {auth}
\ No newline at end of file
......
......@@ -2,6 +2,7 @@ const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const saltRounds = 10;
const jwt = require('jsonwebtoken');
const userSchema = mongoose.Schema({
name : {
type : String,
......@@ -71,16 +72,23 @@ userSchema.methods.generateToken = function(cb){
if(err) return cb(err)
cb(null, user)
})
}
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)
})
})
}
const User = mongoose.model('Users', userSchema)
module.exports = {User}
\ No newline at end of file
......