Commit 22f69a2a authored by Choi Ga Young's avatar Choi Ga Young
Browse files

로그인, 회원가입 서버 연결

parent e399d413
...@@ -3,11 +3,18 @@ import axios from "axios"; ...@@ -3,11 +3,18 @@ import axios from "axios";
const signup = async (user) => { const signup = async (user) => {
const url = `/api/auth/signup`; const url = `/api/auth/signup`;
const { data, status } = await axios.post(url, user); const { data, status } = await axios.post(url, user);
return {data, status} return { data, status }
}
const login = async (user) => {
const url = `/api/auth/login`;
const { data, status } = await axios.post(url, user);
return { data, status }
} }
const authApi = { const authApi = {
signup signup,
login
}; };
export default authApi export default authApi
\ No newline at end of file
import React from 'react'; import { useState } from 'react';
import { Redirect } from "react-router-dom";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { Formik } from 'formik'; import { Formik } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import authApi from '../../apis/auth.api';
import catchErrors from "../../utils/catchErrors.js";
const LoginForm = () => { const LoginForm = () => {
const [success, setSuccess] = useState(false);
const [error, setError] = useState("");
if (success) {
return <Redirect to="/home" />;
}
return ( return (
<> <>
<Formik <Formik
...@@ -17,9 +26,17 @@ const LoginForm = () => { ...@@ -17,9 +26,17 @@ const LoginForm = () => {
password: Yup.string() password: Yup.string()
.required('비밀번호를 입력해주세요.'), .required('비밀번호를 입력해주세요.'),
})} })}
onSubmit={(values, { setSubmitting }) => { onSubmit={async (values, { setSubmitting }) => {
try {
setError("")
const result = await authApi.login(values)
if (result.status === 201) {
setSuccess(true)
}
} catch (error) {
catchErrors(error, setError)
}
setTimeout(() => { setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false); setSubmitting(false);
}, 400); }, 400);
}} }}
......
import React, { useState } from 'react'; import { useState } from 'react';
import { Redirect } from "react-router-dom";
import { Formik } from 'formik'; import { Formik } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import authApi from '../../apis/auth.api'; import authApi from '../../apis/auth.api';
import catchErrors from "../../utils/catchErrors.js";
const SignupForm = () => { const SignupForm = () => {
const [success, setSuccess] = useState(false); const [success, setSuccess] = useState(false);
const [error, setError] = useState("");
if (success) {
return <Redirect to="/login" />;
}
return ( return (
<> <>
<div className="py-5"> <div className="py-5">
...@@ -38,10 +46,15 @@ const SignupForm = () => { ...@@ -38,10 +46,15 @@ const SignupForm = () => {
})} })}
onSubmit={async (values, { setSubmitting }) => { onSubmit={async (values, { setSubmitting }) => {
try { try {
setError("")
const result = await authApi.signup(values) const result = await authApi.signup(values)
// console.log('회원가입 요청 후 result 확인', result, '|', result.status) // console.log('회원가입 요청 후 result 확인', result, '|', result.status)
if (result.status === 201) {
alert("회원가입이 완료되었습니다.")
setSuccess(true)
}
} catch (error) { } catch (error) {
console.log(error) catchErrors(error, setError)
} }
setTimeout(() => { setTimeout(() => {
setSubmitting(false); setSubmitting(false);
......
const config = { const config = {
env: process.env.NODE_ENV === 'production' ? 'production' : 'development', env: process.env.NODE_ENV === 'production' ? 'production' : 'development',
port: process.env.PORT || 3001, port: process.env.PORT || 3001,
jwtSecret: 'lrfp8sQdoLG6eT',
jwtExpires: '30d',
cookieName: 'todayku',
cookieNameMb: 'confirmNum',
cookieMaxAge: 60 * 60 * 24 * 30 * 1000,
} }
export default config export default config
\ No newline at end of file
import jwt from "jsonwebtoken"; import jwt from "jsonwebtoken";
import { User } from '../db/index.js'; import { User } from '../db/index.js';
import config from "../config/app.config.js";
const signup = async (req, res) => { const signup = async (req, res) => {
console.log('server/signup req.body', req.body) console.log('server/signup req.body', req.body)
const { userId, password, userName, userStudNum } = req.body; const { userId, password, userName, userStudNum } = req.body;
try { try {
const findId = await User.findOne({ where: { userID: userId } }); const findId = await User.findOne({ where: { userID: userId } });
console.log('findId type check', findId)
if (findId) { if (findId) {
throw new Error("이미 있는 회원정보 입니다."); throw new Error("이미 있는 회원정보 입니다.");
} }
...@@ -19,14 +19,47 @@ const signup = async (req, res) => { ...@@ -19,14 +19,47 @@ const signup = async (req, res) => {
res.status(201).json("success") res.status(201).json("success")
} catch (error) { } catch (error) {
console.log(error) console.log(error)
res.status(500).send(error.message || "회원가입 에러발생") return res.status(500).send(error.message || "회원가입 에러발생")
} }
// 이건 나중에 정보 있을 때 확인
} }
const login = async (req, res) => { const login = async (req, res) => {
console.log('server/login req.body', req.body) console.log('server/login req.body', req.body)
const { userId, password } = req.body;
try {
const user = await User.scope("withPassword").findOne({ where: { userID: userId } });
console.log('user확인', user)
if (!user) {
return res.status(404).send(`일치하는 정보가 없습니다.`);
}
const passwordMatch = await user.comparePassword(password);
if (passwordMatch) {
const signData = {
id: user.userID,
name: user.userName
};
const token = jwt.sign(signData, config.jwtSecret, {
expiresIn: config.jwtExpires,
});
res.cookie(config.cookieName, token, {
maxAge: config.cookieMaxAge,
path: "/",
httpOnly: config.env === "production",
secure: config.env === "production",
});
res.status(201).json(user)
} else {
res.status(401).send("비밀번호가 일치하지 않습니다.")
}
} catch (error) {
console.log(error)
return res.status(500).send("로그인 에러발생")
}
} }
export default { export default {
......
...@@ -19,6 +19,19 @@ const UserModel = (sequelize) => { ...@@ -19,6 +19,19 @@ const UserModel = (sequelize) => {
studNum: { studNum: {
type: DataTypes.STRING type: DataTypes.STRING
} }
},
{
timestamps: true,
freezeTableName: true,
tableName: "users",
defaultScope: {
attributes: { exclude: ["password"] },
},
scopes: {
withPassword: {
attributes: { include: ["password"] },
},
},
} }
); );
...@@ -31,6 +44,15 @@ const UserModel = (sequelize) => { ...@@ -31,6 +44,15 @@ const UserModel = (sequelize) => {
user.password = hashedPassword; user.password = hashedPassword;
} }
}); });
User.prototype.comparePassword = async function (plainPassword) {
const passwordMatch = await bcrypt.compare(
plainPassword,
this.password
);
return passwordMatch;
};
return User return User
}; };
......
...@@ -9,6 +9,6 @@ router ...@@ -9,6 +9,6 @@ router
router router
.route("/login") .route("/login")
.get(userCtrl.login) .post(userCtrl.login)
export default router; export default router;
\ No newline at end of file
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