Skip to content

Commit

Permalink
Merge : accesstoken으로 로그인 #26
Browse files Browse the repository at this point in the history
Merge : accesstoken으로 로그인
  • Loading branch information
sheepdog13 authored Feb 7, 2024
2 parents 4fab6d2 + 3904bb9 commit 8229899
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 52 deletions.
28 changes: 21 additions & 7 deletions client/src/components/views/Header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import styled from "styled-components";
import SvgIcon from "@mui/material/SvgIcon";
import NightlightIcon from "@mui/icons-material/Nightlight";
import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";

const Wapper = styled.div`
position: fixed;
top: 0;
width: 100%;
height: 64px;
display: flex;
Expand Down Expand Up @@ -173,6 +176,7 @@ const Span = styled.span`
`;

function Header() {
const isLogin = useSelector((state) => state.user.auth.isAuth);
const navigate = useNavigate();
return (
<Wapper>
Expand All @@ -185,13 +189,23 @@ function Header() {
<Logo src={`${process.env.PUBLIC_URL}/img/logo.png`} alt="home" />
<RightBox>
<SvgIcon component={NightlightIcon} fontSize={"large"} />
<LoginBtn
onClick={() => {
navigate("/login");
}}
>
<Span>Login</Span>
</LoginBtn>
{isLogin ? (
<LoginBtn
onClick={() => {
//로그아웃
}}
>
<Span>logout</Span>
</LoginBtn>
) : (
<LoginBtn
onClick={() => {
navigate("/login");
}}
>
<Span>Login</Span>
</LoginBtn>
)}
</RightBox>
</Wapper>
);
Expand Down
14 changes: 14 additions & 0 deletions client/src/components/views/LandingPage/LandingPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ import React from "react";
import Auth from "../../../hoc/auth";
import Header from "../Header/Header";
import styled from "styled-components";
import { useSelector } from "react-redux";

const Wapper = styled.div`
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`;

const H1 = styled.h1`
display: flex;
font-size: 30px;
font-weight: 500;
`;

function LandingPage() {
Expand All @@ -19,9 +29,13 @@ function LandingPage() {
// console.log(err);
// }
// };
const username = useSelector((state) => state.user.auth.name);
const isLogin = useSelector((state) => state.user.auth.isAuth);

return (
<Wapper>
<Header />
{isLogin && <H1>반갑습니다 {username}님!</H1>}
</Wapper>
);
}
Expand Down
8 changes: 4 additions & 4 deletions client/src/components/views/LoginPage/LoginPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import Auth from "../../../hoc/auth";
import styled from "styled-components";
import * as common from "../../../styles/LoginRegister";

const Wapper = styled.div`
margin-top: 100px;
const Wrapper = styled.div`
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
Expand Down Expand Up @@ -38,7 +38,7 @@ function LoginPage() {
};

return (
<Wapper>
<Wrapper>
<common.Form onSubmit={handleSubmit(onSubmit)}>
<common.Title>Login</common.Title>
<common.InputBox>
Expand Down Expand Up @@ -84,7 +84,7 @@ function LoginPage() {
</common.Btn>
</common.BtnBox>
</common.Form>
</Wapper>
</Wrapper>
);
}

Expand Down
8 changes: 4 additions & 4 deletions client/src/components/views/RegisterPage/RegisterPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import Auth from "../../../hoc/auth";
import styled from "styled-components";
import * as common from "../../../styles/LoginRegister";

const Wapper = styled.div`
margin-top: 100px;
const Wrapper = styled.div`
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
Expand Down Expand Up @@ -46,7 +46,7 @@ function RegisterPage() {
};

return (
<Wapper>
<Wrapper>
<common.Form onSubmit={handleSubmit(onSubmit)}>
<common.Title>Sign Up</common.Title>
<common.InputBox>
Expand Down Expand Up @@ -124,7 +124,7 @@ function RegisterPage() {
</common.Btn>
</common.BtnBox>
</common.Form>
</Wapper>
</Wrapper>
);
}

Expand Down
18 changes: 9 additions & 9 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,21 @@ app.post("/api/users/login", async (req, res) => {
});
}

// 토큰 쿠키에 저장
const userdata = await user.generateToken();
// 토큰을 저장한다. 어디에? 쿠키, 로컬스토리지

// user 정보와 access 토큰을 받아온다.
const [userdata, accesstoken] = await user.generateToken();
// refresh 토큰의 옵션
const options = {
httpOnly: true,
sameSite: "None",
secure: true,
// 2주
maxAge: 14 * 24 * 60 * 60 * 1000,
};
// access 토큰은 body로 넘겨주고 refresh 토큰은 cookie에 저장한다.
res.cookie("refreshtoken", userdata.token, options).status(200).json({
accestoken: userdata.token,
accesstoken,
loginSuccess: true,
userId: userdata._id,
name: userdata.name,
});
} catch (err) {
return res.status(400).send(err);
Expand All @@ -102,10 +104,8 @@ app.post("/api/users/login", async (req, res) => {
app.get("/api/users/auth", auth, (req, res) => {
// 미들웨어 통과후이기 때문에 Authentication이 True라는 말
res.status(200).json({
_id: req.user._id,
isAdmin: req.user.role === 0 ? false : true,
name: req.name,
isAuth: true,
email: req.user.email,
});
});

Expand Down
46 changes: 26 additions & 20 deletions server/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
const { User } = require("../models/User");
const jwt = require("jsonwebtoken");
// 인증 처리를 하는곳
let auth = async (req, res, next) => {
// 클라이언트에서 토큰을 가져온다
let token = req.headers.authorization;
if (token) {
const userdata = await User.findByToken(token);
req.user = userdata;
return next();
// 클라이언트에서 헤더로 보내준 accesstoken
let accesstoken = req.headers.authorization;
// accesstoken이 있을때 조작된 jwt인지 확인후 미들웨어 종료
if (accesstoken) {
try {
const userdata = jwt.verify(accesstoken.split(" ")[1], "secretToken");
req.name = userdata.username;
next();
} catch (err) {
return res.json({ isAuth: false, error: err });
}
} else {
// refresh 토큰으로 access 토큰 재발급
}
try {
// 토큰을 복호화 한후 유저를 찾는다.
const userdata = await User.findByToken(token);
// 유저가 업으면 no
if (!userdata) return res.json({ isAuth: false, error: true });
// 같은 유저가 있으면 ok
// 미들웨어가 끝나고 req에서 사용할 수 있게 데이터를 보내준다.
req.token = token;
req.user = userdata;
next();
} catch (err) {
return res.json({ isAuth: false, error: err });
return res.json({ isAuth: false });
}
// try {
// // 토큰을 복호화 한후 유저를 찾는다.
// const userdata = await User.findByToken(token);
// // 유저가 업으면 no
// if (!userdata) return res.json({ isAuth: false, error: true });
// // 같은 유저가 있으면 ok
// // 미들웨어가 끝나고 req에서 사용할 수 있게 데이터를 보내준다.
// req.token = token;
// req.user = userdata;
// next();
// } catch (err) {
// return res.json({ isAuth: false, error: err });
// }
};

module.exports = { auth };
17 changes: 9 additions & 8 deletions server/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,19 @@ userSchema.methods.comparePassword = function (plainPassword) {
};

// 토큰 발급 메서드
userSchema.methods.generateToken = async function (cb) {
userSchema.methods.generateToken = async function () {
var user = this;
// jsonwebtoken을 이용해서 token을 생성하기
var token = jwt.sign(user._id.toHexString(), "secretToken");
// user._id(db의 _id) + secreToken = token
// token으로 user를 판별할 수 있다.
// user.token = token;
user.token = token;
var accesstoken = jwt.sign({ username: user.name }, "secretToken", {
expiresIn: "5m",
});
var refreshtoken = jwt.sign(user._id.toHexString(), "secretToken");
// refreshtoken을 db에 저장한다.
user.token = refreshtoken;

try {
const savedUser = await user.save();
return user;
return [user, accesstoken];
} catch (err) {
return err;
}
Expand All @@ -88,7 +89,7 @@ userSchema.statics.findByToken = async function (token) {
// 코인을 decode 한다.
const decodedtoken = jwt.verify(token, "secretToken");
// 복호화된 토큰에서 user_id와 같은 유저 찾기
const userdata = await user.findOne({ _id: decodedtoken, token: token });
const userdata = await user.findOne({ _id: decodedtoken });
return userdata;
} catch (err) {
throw err;
Expand Down

0 comments on commit 8229899

Please sign in to comment.