Commit 1c9e6868 authored by Choi Ga Young's avatar Choi Ga Young
Browse files

private라우터 적용/ 회원가입, 로그인 수정, Menu 수정

parent 36320a85
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.1", "react-scripts": "4.0.1",
"socket.io-client": "^3.0.5",
"styled-components": "^5.2.1", "styled-components": "^5.2.1",
"web-vitals": "^0.2.4" "web-vitals": "^0.2.4"
}, },
......
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Form, Button, Row } from 'react-bootstrap'; import { Form, Button, Row } from 'react-bootstrap';
import axios from "axios"; // import axios from "axios";
function Chat(props) { function Chat(props) {
const [username, setUsername] = useState('') // const [username, setUsername] = useState('')
const username = localStorage.getItem('name');
function handleChange(e) { function handleChange(e) {
e.preventDefault() e.preventDefault()
...@@ -16,15 +17,18 @@ function Chat(props) { ...@@ -16,15 +17,18 @@ function Chat(props) {
props.sendMsg(e) props.sendMsg(e)
} }
async function getLoginedUser() { //email로 db에서 찾아오기 ㅇㅇㅇㅇㅇ // async function getLoginedUser() { //email로 db에서 찾아오기
const userid = localStorage.getItem('user')
const response = await axios.post(`/users/${userid}`, { 'email': userid }) // const userid = localStorage.getItem('user')
setUsername(response.data.username) // const response = await axios.post(`/users/${userid}`, { 'email': userid })
} // setUsername(response.data.username)
useEffect(() => { // }
getLoginedUser()
console.log('Chat에서 useEffect', username) // useEffect(() => {
}) // getLoginedUser()
// console.log('Chat에서 useEffect', username)
// })
return ( return (
<div className="chat" id="chat" style={{ border: "2px solid", height: "300%", margin: "1%", borderColor: "#BDBDBD" }}> <div className="chat" id="chat" style={{ border: "2px solid", height: "300%", margin: "1%", borderColor: "#BDBDBD" }}>
...@@ -41,14 +45,6 @@ function Chat(props) { ...@@ -41,14 +45,6 @@ function Chat(props) {
<Button variant="primary" type="submit">전송</Button> <Button variant="primary" type="submit">전송</Button>
</Form> </Form>
<Form>
<Form.Group>
<Form.Control type="text" />
</Form.Group>
<Button variant="primary" type="submit">
전송
</Button>
</Form>
</div> </div>
......
...@@ -3,13 +3,15 @@ import { Navbar, Nav, Button } from 'react-bootstrap'; ...@@ -3,13 +3,15 @@ import { Navbar, Nav, Button } from 'react-bootstrap';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { handleLogout } from '../utils/auth'; import { handleLogout } from '../utils/auth';
function Menu() { function Menu() {
const userName = "정연우";
const name = localStorage.getItem('name');
return ( return (
<Navbar bg="dark" variant="dark"> <Navbar bg="dark" variant="dark">
<Navbar.Brand href="/home">YDK Messenger</Navbar.Brand> <Navbar.Brand href="/home">YDK Messenger</Navbar.Brand>
<div className='ml-1 mr-2' style={{ color: 'white' }}>{userName} 환영합니다</div> <div className='ml-1 mr-2' style={{ color: 'white' }}>{name} 환영합니다</div>
<Nav className="mr-auto"> <Nav className="mr-auto">
<Nav.Link href="/home">Home</Nav.Link> <Nav.Link href="/home">Home</Nav.Link>
<Nav.Link href="/profile">Profile</Nav.Link> <Nav.Link href="/profile">Profile</Nav.Link>
......
import React from 'react'
import { Redirect, Route } from 'react-router-dom'
import { isAuthenticated } from '../utils/auth'
function PrivateRoute({ path, children }) {
if (isAuthenticated()) {
return (
<Route path={path}>
{children}
</Route>
)
} else {
return (
<Redirect to='/login'/>
)
}
}
export default PrivateRoute
\ No newline at end of file
import { Button, Navbar, Nav } from 'react-bootstrap';
import React from 'react'
const userName = "정연우";
function Hello(props) {
console.log(props)
return (
<>
<Navbar bg="dark" variant="dark">
<Navbar.Brand href="/homepage">YDK Messenger</Navbar.Brand>
<div className='ml-1 mr-2' style={{ color: 'white' }}>{userName} 환영합니다</div>
<Nav className="mr-auto">
<Nav.Link href="/home">Home</Nav.Link>
<Nav.Link href="/profile">Profile</Nav.Link>
<Nav.Link href="/hello">Hello</Nav.Link>
</Nav>
{/* <Form inline>
<FormControl type="text" placeholder="Search" className="mr-sm-2" />
<Button variant="outline-info">Search</Button>
</Form> */}
<Button variant="light" className="ml-3">Logout</Button>
</Navbar>
<h1>hello</h1>
<div>
안녕하세요.{props.name}
</div>
<input className="input" />
</>
)
}
export default Hello;
...@@ -6,31 +6,24 @@ import ClosedList from '../Components/ClosedList'; ...@@ -6,31 +6,24 @@ import ClosedList from '../Components/ClosedList';
import OpenList from '../Components/OpenList'; import OpenList from '../Components/OpenList';
import Chat from '../Components/Chat'; import Chat from '../Components/Chat';
import Menu from '../Components/Menu'; import Menu from '../Components/Menu';
// import styled from 'styled-components';
import { io } from "socket.io-client"; //모듈 가져오기 import { io } from "socket.io-client"; //모듈 가져오기
// const List = styled.div` // const userName = "정연우";
// background: #FFFAFA;
// `
const userName = "정연우";
const socket = io(); const socket = io();
function Home() { function Home() {
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const [chat, setChat] = useState(false); const [chat, setChat] = useState(false);
const handleClose = () => setShow(false); const handleClose = () => setShow(false);
const handleShow = () => setShow(true); const handleShow = () => setShow(true);
const handleChato = () => setChat(true); const handleChato = () => setChat(true);
const handleChatc = () => setChat(false); const handleChatc = () => setChat(false);
// variant="pills"
/////////////////////////////////////////////////////////////// const [inner, setInner] = useState(['']) //인풋값
const [inner, setInner] = useState(['']) const [chatmsg, setChatmsg] = useState([inner]) // 전송된 채팅들 저장하는 배열
console.log('sendMsg2222', inner)
const [chatmsg, setChatmsg] = useState([inner])
const [roomName, setRoomName] = useState('dd') //방 선택이 방1을 눌럿다 방2를 누르면 전체로 전송됨 const [roomName, setRoomName] = useState('dd') //방 선택이 방1을 눌럿다 방2를 누르면 전체로 전송됨
function enterChatroom(roomName) { //방 입장하기 function enterChatroom(roomName) { //방 입장하기
...@@ -53,7 +46,6 @@ function Home() { ...@@ -53,7 +46,6 @@ function Home() {
} }
useEffect(() => { useEffect(() => {
console.log('useeffect1')
socket.on('broadcast', (msg) => { socket.on('broadcast', (msg) => {
console.log('msg', msg) console.log('msg', msg)
...@@ -64,13 +56,6 @@ function Home() { ...@@ -64,13 +56,6 @@ function Home() {
}) })
console.log('useeffect2', chatmsg) console.log('useeffect2', chatmsg)
}, [chatmsg]) }, [chatmsg])
//////////////////////////////////////////////////////////
return ( return (
......
...@@ -4,6 +4,7 @@ import { Button, Form, Container, Navbar, Spinner, Alert } from 'react-bootstrap ...@@ -4,6 +4,7 @@ import { Button, Form, Container, Navbar, Spinner, Alert } from 'react-bootstrap
import catchErrors from '../utils/catchErrors' import catchErrors from '../utils/catchErrors'
import { Link, Redirect } from 'react-router-dom' import { Link, Redirect } from 'react-router-dom'
import { handleLogin } from '../utils/auth' import { handleLogin } from '../utils/auth'
// import Menu from '../Components/Menu';
const INIT_USER = { const INIT_USER = {
email: '', email: '',
...@@ -11,9 +12,7 @@ const INIT_USER = { ...@@ -11,9 +12,7 @@ const INIT_USER = {
} }
function LogIn() { function LogIn() {
const [validated, setValidated] = useState(false);
const [user, setUser] = useState(INIT_USER) const [user, setUser] = useState(INIT_USER)
//로딩, 에러, diserved 상태 넣어야됨.
const [disabled, setDisabled] = useState(true) const [disabled, setDisabled] = useState(true)
const [error, setError] = useState('') const [error, setError] = useState('')
const [success, setSucces] = useState(false) const [success, setSucces] = useState(false)
...@@ -21,34 +20,21 @@ function LogIn() { ...@@ -21,34 +20,21 @@ function LogIn() {
useEffect(() => { useEffect(() => {
const isUser = Object.values(user).every(el => Boolean(el)) const isUser = Object.values(user).every(el => Boolean(el))
//Boolean : 참거짓 판별
//every : every뒤에 함수값이 return하는 값이 모두 참일때만 true출력 -> element가 하나도 빈 문자열이 존재하지 않을때
//empty string때만 false로 나옴.
isUser ? setDisabled(false) : setDisabled(true) isUser ? setDisabled(false) : setDisabled(true)
}, [user]) }, [user])
function handleChange(event) { function handleChange(event) {
const { name, value } = event.target const { name, value } = event.target
// console.log(name, value)
setUser({ ...user, [name]: value }) setUser({ ...user, [name]: value })
} }
async function handleSubmit(event) { async function handleSubmit(event) {
event.preventDefault() event.preventDefault()
// const form = event.currentTarget;
// if (form.checkValidity() === false) {
// event.preventDefault();
// event.stopPropagation();
// }
// setValidated(true);
try { try {
setLoading(true) setLoading(true)
setError('') setError('')
await axios.post('/auth/login', user) let res = await axios.post('/auth/login', user)
// 알아서 stringify하기 때문에 따로 해줄 필요 없음. handleLogin(res.data)
handleLogin(user)
setSucces(true) setSucces(true)
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
...@@ -68,16 +54,13 @@ function LogIn() { ...@@ -68,16 +54,13 @@ function LogIn() {
return ( return (
<> <>
{/* <Navbar bg="dark" variant="dark"> <Navbar bg="dark" variant="dark">
<Navbar.Brand>YDK Messenger</Navbar.Brand> <Navbar.Brand>YDK Messenger</Navbar.Brand>
</Navbar> */} </Navbar>
<Form onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'>
<Form noValidate validated={validated} onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'>
<Container className="d-flex justify-content-center"> <Container className="d-flex justify-content-center">
<div className="mt-5 p-5 shadow w-75"> <div className="mt-5 p-5 shadow w-75">
<h2 className="text-center">로그인</h2> <h2 className="text-center">로그인</h2>
<Form.Group controlId="formGroupEmail"> <Form.Group controlId="formGroupEmail">
<Form.Label>이메일</Form.Label> <Form.Label>이메일</Form.Label>
<Form.Control <Form.Control
......
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import axios from 'axios' import axios from 'axios'
import { Button, Form, Container, Navbar, Alert } from 'react-bootstrap'; import { Button, Form, Container, Alert, Navbar } from 'react-bootstrap';
import catchErrors from '../utils/catchErrors'; import catchErrors from '../utils/catchErrors';
import { Redirect } from 'react-router-dom'; import { Redirect } from 'react-router-dom';
...@@ -20,15 +20,11 @@ function SingUp() { ...@@ -20,15 +20,11 @@ function SingUp() {
useEffect(() => { useEffect(() => {
const isUser = Object.values(user).every(el => Boolean(el)) const isUser = Object.values(user).every(el => Boolean(el))
//Boolean : 참거짓 판별
//every : every뒤에 함수값이 return하는 값이 모두 참일때만 true출력 -> element가 하나도 빈 문자열이 존재하지 않을때
//empty string때만 false로 나옴.
isUser ? setDisabled(false) : setDisabled(true) isUser ? setDisabled(false) : setDisabled(true)
}, [user]) }, [user])
function handleChange(event) { function handleChange(event) {
const { name, value } = event.target const { name, value } = event.target
// console.log(name, value)
setUser({ ...user, [name]: value }) setUser({ ...user, [name]: value })
} }
...@@ -46,23 +42,8 @@ function SingUp() { ...@@ -46,23 +42,8 @@ function SingUp() {
try { try {
setError('') setError('')
// const response = await fetch('/api/users/signup', {
// //post, get같은게 주어지지 않으면 기본적으로 fetch에 get요청함
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json'
// },
// body: JSON.stringify(user)
// })
// const data = await response.json()
await axios.post('/users/signup', user) await axios.post('/users/signup', user)
// 알아서 stringify하기 때문에 따로 해줄 필요 없음. alert("회원가입이 완료되었습니다!")
// console.log(response.data)
console.log(user)
// ?????????hash 처리된 password가 저장되지 않았음
// setUser(INIT_USER)
setSucces(true) setSucces(true)
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
...@@ -77,9 +58,9 @@ function SingUp() { ...@@ -77,9 +58,9 @@ function SingUp() {
return ( return (
<> <>
{/* <Navbar bg="dark" variant="dark"> <Navbar bg="dark" variant="dark">
<Navbar.Brand>YDK Messenger</Navbar.Brand> <Navbar.Brand>YDK Messenger</Navbar.Brand>
</Navbar> */} </Navbar>
<Form noValidate validated={validated} onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'> <Form noValidate validated={validated} onSubmit={handleSubmit} className='vh-100 flex-column align-items-center justify-content-center mt-2'>
<Container className="d-flex justify-content-center"> <Container className="d-flex justify-content-center">
......
...@@ -2,27 +2,31 @@ import React from 'react'; ...@@ -2,27 +2,31 @@ import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css'; import './index.css';
// import App from './App'; import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom';
import reportWebVitals from './reportWebVitals';
import SignUpPage from './Pages/SignUpPage'; import SignUpPage from './Pages/SignUpPage';
import ProfilePage from './Pages/ProfilePage'; import ProfilePage from './Pages/ProfilePage';
import reportWebVitals from './reportWebVitals';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import LogInPage from './Pages/LogInPage'; import LogInPage from './Pages/LogInPage';
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom';
import Hello from './Hello'
import HomePage from './Pages/HomePage' import HomePage from './Pages/HomePage'
import PrivateRoute from './Components/PrivateRoute';
ReactDOM.render( ReactDOM.render(
<Router> <Router>
<Switch> <Switch>
<Route exact path="/" component={HomePage} /> <PrivateRoute exact path="/">
<HomePage />
</PrivateRoute>
<Route path="/home" component={HomePage} />
<Route path="/login" component={LogInPage} /> <Route path="/login" component={LogInPage} />
<Route path="/signup" component={SignUpPage} /> <Route path="/signup" component={SignUpPage} />
<Route path="/profile" component={ProfilePage} /> <Route path="/profile" component={ProfilePage} />
<Route path="/hello" component={Hello} /> {/* <PrivateRoute path="/profile">
<Route path="/home" component={HomePage} /> <ProfilePage />
<Redirect path='/hello' to='/hello' /> </PrivateRoute> */}
</Switch> </Switch>
</Router>, </Router>,
document.getElementById('root') document.getElementById('root')
......
import axios from "axios" import axios from "axios"
//자동으로 localstorage에 login이 생성됨 //자동으로 localstorage에 login이 생성됨
export function handleLogin(props) { export function handleLogin(data) {
localStorage.setItem('user', props.email) localStorage.setItem('userId', data.user._id)
localStorage.setItem('name', data.user.username)
} }
export async function handleLogout() { export async function handleLogout() {
localStorage.removeItem('user') localStorage.clear();
await axios.get('/auth/logout') await axios.get('/auth/logout')
}
export function isAuthenticated() {
const userId = localStorage.getItem('userId')
if (userId) {
return userId
} else {
return false
}
} }
\ No newline at end of file
...@@ -16,9 +16,16 @@ ...@@ -16,9 +16,16 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "^0.21.1",
"bcrypt": "^5.0.0",
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"express": "^4.17.1", "express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.11.9", "mongoose": "^5.11.9",
"nanoid": "^3.1.20",
"nodemon": "^2.0.6", "nodemon": "^2.0.6",
"socket.io": "^3.0.5",
"validator": "^13.5.2" "validator": "^13.5.2"
} }
} }
...@@ -39,7 +39,8 @@ const login = async (req, res) => { ...@@ -39,7 +39,8 @@ const login = async (req, res) => {
secure: config.env === 'production', secure: config.env === 'production',
//secure가 true이면 http로 접근하면 cookie가 들어가지 않음. //secure가 true이면 http로 접근하면 cookie가 들어가지 않음.
}) })
res.send('Login Successful') console.log('res.send.user', {user})
res.send({user})
} else { } else {
// 5) 비밀번호가 틀리면 에러 반환 // 5) 비밀번호가 틀리면 에러 반환
......
...@@ -4,20 +4,14 @@ import isEmail from 'validator/lib/isEmail.js' ...@@ -4,20 +4,14 @@ import isEmail from 'validator/lib/isEmail.js'
import bcrypt from "bcryptjs"; import bcrypt from "bcryptjs";
import jwt from 'jsonwebtoken' import jwt from 'jsonwebtoken'
import config from "../config.js" import config from "../config.js"
//꼭 js붙여주기!!
//sign validation해야됨
const signup = async (req, res) => { const signup = async (req, res) => {
const { username, nickname, email, password } = req.body const { username, nickname, email, password } = req.body
//req.body를 구조분해하여 각각 보이게함 -> 모든정보들이 한줄에 보임
console.log(username, nickname, email, password)
try { try {
if (!isLength(username, { min: 3, max: 10 })) { if (!isLength(username, { min: 3, max: 10 })) {
//이범위를 벗어나면 error발생
return res.status(422).send('이름은 3-10자 사이입니다') return res.status(422).send('이름은 3-10자 사이입니다')
//422 : 형식이 잘못되었다는 error발생
} else if (!isLength(nickname, { min: 2, max: 10 })) { } else if (!isLength(nickname, { min: 2, max: 10 })) {
return res.status(422).send('별명은 2-10자 사이입니다.') return res.status(422).send('별명은 2-10자 사이입니다.')
} else if (!isLength(password, { min: 6 })) { } else if (!isLength(password, { min: 6 })) {
...@@ -25,36 +19,21 @@ const signup = async (req, res) => { ...@@ -25,36 +19,21 @@ const signup = async (req, res) => {
} else if (!isEmail(email)) { } else if (!isEmail(email)) {
return res.status(422).send('유효하지 않은 이메일 형식입니다') return res.status(422).send('유효하지 않은 이메일 형식입니다')
} }
// else if (!isLength(nickname, { min: 3, max: 10 })) {
// return res.status(422).send('Nickname must be 3-10 characters')
// } else if (!isEmail(email, {
// allow_display_name: true,
// require_display_name: true,
// allow_utf8_local_part: false,
// })) {
// return res.status(422).send('Email does not fit the format')
// } else if (!isLength(password, { min: 6, max: 25 })) {
// return res.status(422).send('Nickname must be 6-25 characters')
// }
// 기존의 email이 있으면 나오는 error (unique)
const user = await User.findOne({ email }) const user = await User.findOne({ email })
if (user) { if (user) {
return res.status(422).send(`${email}이 이미 사용중입니다.`) return res.status(422).send(`${email}이 이미 사용중입니다.`)
} }
const hash = await bcrypt.hash(password, 10) const hash = await bcrypt.hash(password, 10)
//promise이므로 await사용함
const newUser = await new User({ const newUser = await new User({
username, username,
nickname, nickname,
email, email,
password: hash, password: hash,
//required를 하였기 때문에 이중 하나라도 없으면 에러 발생
}).save() }).save()
//save시 user schema형식에 맞는지 확인후 틀리면 error발생 맞으면 mongooDb로 들어감
//save(promise)붙일 시 fuction 앞에 await 붙여주기 + async 함수 앞에 붙여주기
console.log(newUser) console.log(newUser)
res.json(newUser) res.json(newUser)
...@@ -69,8 +48,6 @@ const hello = async (req, res) => { ...@@ -69,8 +48,6 @@ const hello = async (req, res) => {
return res.json(users) return res.json(users)
} }
const logineduser = async (req, res) => { const logineduser = async (req, res) => {
try { try {
let user = await User.findOne(req.body).select('username email nickname').exec() let user = await User.findOne(req.body).select('username email nickname').exec()
......
...@@ -13,17 +13,4 @@ router.route(`/users/:userId`) ...@@ -13,17 +13,4 @@ router.route(`/users/:userId`)
.put(userCtrl.changenick) .put(userCtrl.changenick)
// router.route('/api/users/signup/:userId') //로그인한 사람의 정보만 가져오도록
// .get
// /api/users/signup로 들어오는 것을 post (method) 를 통해 useCtrl.signup 이것이 처리함
//browser에서 주소창에 치고 들어가면 get (method) 을 타고 들어간것임
//post를 띄우고 싶으면 앱에서 ARC실행해서 post를 실행하게 만들면됨.
//객체에 접근할때는 .을 찍고 접근함/ ex) .hello
//express middleware : (req, res) => {}
//node(req(client의 정보), res)를 넘겨줌.
export default router export default router
\ No newline at end of file
...@@ -4,7 +4,6 @@ import userRouter from './routes/user.routes.js' ...@@ -4,7 +4,6 @@ import userRouter from './routes/user.routes.js'
import authRouter from './routes/auth.routes.js' import authRouter from './routes/auth.routes.js'
import profileRouter from './routes/profile.routes.js' import profileRouter from './routes/profile.routes.js'
import cors from "cors";
import bodyParser from "body-parser"; import bodyParser from "body-parser";
import http from "http"; import http from "http";
import { Server } from 'socket.io'; import { Server } from 'socket.io';
...@@ -46,11 +45,6 @@ io.on("connection", (socket) => { // 기본 연결 ...@@ -46,11 +45,6 @@ io.on("connection", (socket) => { // 기본 연결
//이부분을 body 파싱함 //이부분을 body 파싱함
app.use(bodyParser.json()); app.use(bodyParser.json());
// app.use(cors());
// app.use('/', indexRouter);
//express가 req.body라는곳을 자동으로만들어서 json형식으로 보낸것을 객체형식으로 넣음
//이부분 다음부터는 req.body라는 부분을 실행할 수 있음
app.use(userRouter) app.use(userRouter)
app.use(authRouter) app.use(authRouter)
app.use(profileRouter) app.use(profileRouter)
...@@ -64,9 +58,5 @@ server.listen(3030, () => { ...@@ -64,9 +58,5 @@ server.listen(3030, () => {
console.log('Listening on port 3030') console.log('Listening on port 3030')
}) })
/////////////////////////////////////////////////////////
// export default server // export default server
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment