반응형
PedroTech님의 풀스택 강의 8일 차를 참고했습니다.
📌 로그인 정보를 저장할 Users 테이블 생성하기
// ./server/models/Users.js
module.exports = (sequelize, DataTypes) => {
const Users = sequelize.define("Users", {
username: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
});
return Users;
};
Users 테이블 안에는 username(사용자 이름)과 password(비밀번호)를 저장할 수 있습니다.
📌 bcrypt 설치하기
npm install bcrypt
server 폴더 위치로 이동 후, 터미널에 위와 같이 입력하면 bcrypt가 설치됩니다.
bcrypt를 사용하는 이유: 특정 데이터를 암호화해야 할 때 유용하게 사용되기 때문에 비밀번호 암호화를 위해 활용했습니다.
📌 Users의 router 생성하기
// ./server/routers/Users.js
const express = require("express");
const router = express.Router();
const { Users } = require("../models");
// 암호화하기 위해 사용합니다.
const bcrypt = require("bcrypt");
// *첫 번째 POST(회원가입하기)
router.post("/", async (req, res) => {
const { username, password } = req.body;
// 비밀번호 암호화를 해줍니다.
bcrypt.hash(password, 10).then((hash) => {
Users.create({
username: username,
password: hash,
});
res.json("SUCCESS");
});
});
// *두 번째 POST(로그인하기)
router.post("/login", async (req, res) => {
const { username, password } = req.body;
const user = await Users.findOne({ where: { username: username } });
if (!user) {
res.json({ error: "User Doesn't Exist" });
}
// password가 일치하는지 비교해줍니다.
bcrypt.compare(password, user.password).then((match) => {
if (!match) {
res.json({ error: "Wrong Username And Password Combination" });
}
res.json("YOU LOGED IN!!");
});
});
module.exports = router;
// install bcrypt
회원가입 코드 설명
1. req.body: 데이터(username, password)를 반환합니다.
2. bcrypt.hash(데이터, 암호화 값): 전달받은 데이터를 암호화해서 테이블에 저장될 수 있도록 해줍니다.
(암호화 값은 커질 수록 암호화 연산이 증가하게 되어 보안을 높이는데 도움이 됩니다.)
3. Users.create(): Users라는 테이블에 값을 저장하라는 의미입니다.
로그인 코드 설명
1. Users.findOne({where: ... }): Users 테이블에서 조건(where)에 맞는 데이터 1개만 가져옵니다.
2. if (!user) {}와 if(!match): 조건과 맞는 데이터가 없을 때 실행되는 조건문입니다.
3. bcrypt.compare(데이터1, 데이터2): 매개변수들을 비교해서 성공적으로 되면 then을 실행시킵니다.
(데이터1: 사용자가 입력한 값, 데이터2: Users 테이블에서 가져온 데이터)
📌 React에서 사용할 수 있도록 Users router 등록하기
// ./server/index.js
const usersRouter = require("./routes/Users");
app.use("/auth", usersRouter);
Users의 router를 사용하고 싶을 땐 http://localhost:0000/auth를 이용해야 합니다.
📌 회원가입 화면 만들기
import React from "react";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import axios from "axios";
function Registration() {
const initialValues = {
username: "",
password: "",
};
const validationSchema = Yup.object().shape({
username: Yup.string().min(3).max(15).required(),
password: Yup.string().min(4).max(20).required(),
});
const onSubmit = (data) => {
axios.post("http://localhost:3001/auth", data).then(() => {
console.log(data);
});
};
return (
<div>
<Formik
initialValues={initialValues}
onSubmit={onSubmit}
validationSchema={validationSchema}
>
<Form>
<label htmlFor="inputUsername">Username: </label>
<ErrorMessage name="username" component="span" />
<Field
autoComplete="off"
id="inputUsername"
name="username"
placeholder="(Ex. User12...)"
/>
<label htmlFor="inputPassword">Password: </label>
<ErrorMessage name="password" component="span" />
<Field
autoComplete="off"
type="password"
id="inputPassword"
name="password"
placeholder="Your Password"
/>
<button type="submit">
Register
</button>
</Form>
</Formik>
</div>
);
}
export default Registration;
(Formik와 각종 함수들의 내용은 React, MySQL 풀스택 4일 차를 참고해 주시기 바랍니다.)
함수 코드 설명
1. onSubmit(): axios를 활용해서 Users 테이블로 데이터를 보내줍니다.
화면 구성 코드 설명
1. Field의 type: input 태그와 동일한 의미를 가지고 있습니다.
📌 로그인 화면 만들기
import React, { useState } from "react";
import axios from "axios";
function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const login = () => {
const data = { username: username, password: password };
axios.post("http://localhost:3001/auth/login", data).then((response) => {
console.log(response.data);
});
};
return (
<div>
<label htmlFor="inputUsername">Username: </label>
<input
type="text"
id="inputUsername"
onChange={(e) => setUsername(e.target.value)}
/>
<label htmlFor="inputPassword">Password: </label>
<input
type="password"
id="inputPassword"
onChange={(e) => setPassword(e.target.value)}
/>
<button type="button" onClick={login}>
Login
</button>
</div>
);
}
export default Login;
함수 설명
1. login(): 로그인 정보를 지정된 경로로 전달한 뒤, 로그인을 성공했는지 아닌지를 확인합니다.
2. setUsername(): 사용자 이름을 저장하는 함수입니다.
3. setPassword(): 비밀번호를 저장하는 함수입니다.
화면 구성 코드 설명
1. input태그의 onChange(): 사용자가 값을 입력할 때마다 해당 값을 지정된 변수에 저장합니다.
📌 App.js에 회원가입, 로그인 경로 정의하기
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import Login from "./pages/Login";
import Registration from "./pages/Registration";
function App() {
return (
<div className="App">
<BrowserRouter>
<div className="nav">
...
<Link to="/login" className="link">
Login
</Link>
<Link to="/registration" className="link">
Registration
</Link>
</div>
<Routes>
...
<Route path="/login" exact element={<Login />} />
<Route path="/registration" exact element={<Registration />} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
React에서 성공적으로 경로를 이동하기 위해 react-router-dom을 활용해서 Login과 Registration을 정의해줍니다.
📌 결과
1. 회원가입
2. 로그인
📌 느낀 점
회원가입을 하고 나서 비밀번호를 암호화하는 과정을 처음 해봤습니다. 보안을 위해 bcrypt라는 기능을 사용한다는 걸 알게 된 후 찾아보니 여러 방법들로 암호화를 할 수 있더라고요!
나중에 회원가입 기능을 구현해야 할 때 상황에 맞게 적절한 것으로 사용해야겠다는 생각이 들었습니다.
오늘 한 것들은 대부분 전에 했던 것과 비슷한 부분이 많아서 중복되는 설명은 링크로 전달해 봤습니다.
다음에는 로그인 정보가 있는 사람만 글을 쓸 수 있도록 하는 기능도 만들고 싶네요!
참고 사이트: [NODE] 📚 bcrypt 모듈 암호화 원리 & 사용법
728x90
'MySQL' 카테고리의 다른 글
React, MySQL 10일차 (댓글 작성자 화면에 표시하기) (0) | 2023.10.24 |
---|---|
React, MySQL 풀스택 9일차 (로그인 암호화해서 세션에 저장하기) (2) | 2023.10.21 |
React, MySQL 7일차 (댓글 보여주기) (0) | 2023.10.15 |
React, MySQL 6일차 (테이블에 외래키 추가하기) (3) | 2023.10.15 |
CSV 파일을 DB에 가져오기 (HeidiSQL 사용) (0) | 2023.10.09 |