일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- mypage
- 로그인 로직
- 빌드 및 배포
- Styled Components
- 밸류즈 홈페이지
- 달력 라이브러리
- stock option
- react
- 이미지 업로드
- jsonwebtoken
- register
- 인증처리
- 파생상품평가
- ui탬플릿
- 캘린더 라이브러리
- Typesciprt
- Ajax
- MRC
- 로그인
- 공통메서드
- 관리자페이지
- Token
- 회원가입로직
- 배포
- RCPS
- userManagement
- 마이페이지
- 밸류즈
- Update
- 스프링시큐리티
- Today
- Total
I T H
[MySchedule project] 7. JWT(json web token) / 로그인 로직(2) 본문
이번 챕터는 로그인 로직 2번째 - 백앤드로부터 받아온 토큰을 headers의 Authorization에 넣어 백앤드로 보내고 백앤드에서 지정해놓은 secret key를 이용해 유효한 토큰인지 확인한 후 데이터를 프론트로 전달하는 단계까지 하도록 하겠다.
- 로그인 뿐만 아니라 인증이 필요한 경우가 많으므로, 로그인 후에 인증요청시 토큰을 보내서 백앤드에서 유효한 토큰인지 확인하는 과정이다.
- Frontend
[ App.tsx ]
- redux store에 저장된 데이터를 가져오기 위해 useSelector를 사용한다. 타입을 미리 지정해놓았기 때문 useAddSelector를 통해 isAuth를 불러와서 사용하도록 하였다.
- isAuth 부분이 true가 되었다면 로그인이 완료되었다는 뜻이므로, 로그인이 정상적으로 되었다면 useEffect부분을 탈수 있도록 의존성배열 [ ] 에 isAuth를 추가해준다.
- pathName은 useLocation에서 불러온 현재주소 경로인데 주소가 바뀔때마다 authCheck()를 타게 의존성배열에 추가해주었다.
const isAuth = useAddSelector((state) => state.user?.isAuth);
const role = useAddSelector((state) => state.user?.userData?.role);
const dispatch = useAddDispatch();
const { pathname } = useLocation(); //현재주소 경로
//인증이 잘되었는지 체크
useEffect(() => {
if (isAuth) {
dispatch(authCheck());
}
}, [isAuth, dispatch, pathname]);
[ src / utils / axios.js ]
- thunkFunction으로 넘어가기에 앞서 axiosInstance부분에서 config.headers의 Authorization에 토큰을 넣는 부분을 추가해 준다.
- 토큰이 만료되었을때 처리하는 로직도 넣어주었음.
axiosInstance.interceptors.request.use(
//전처리
function (config) {
config.headers.Authorization =
"Bearer " + localStorage.getItem("accessToken");
return config;
},
function (error) {
return Promise.reject(error);
}
);
//토큰이 만료되었을때 처리하는 로직
axiosInstance.interceptors.response.use(
//후처리
function (response) {
return response;
},
function (error) {
if (error.response.data === "jwt expired") {
//jwt expired => 토큰이 만료되었다면
window.location.reload(); //페이지 리프레시
}
return Promise.reject(error);
}
);
[ src / store / thunkFunction.tsx ]
- 백앤드로 headers의 Authorization에 넣은 토큰을 전달해준다.
//인증이 되어있는지 체크하는 로직
//인증된 토큰이면 백앤드에서 미들웨어 auth를 만들어서 유저데이터를 사용할수있도록 처리
export const authCheck = createAsyncThunk(
"user/authCheck",
async (_, thunkAPI) => {
try {
const response = await axiosInstance.get(`/authCheck`);
return response.data;
} catch (error: any) {
console.log(error);
return thunkAPI.rejectWithValue(error.response.data || error.message);
}
}
);
- Backend
[ src / index.js]
- 경로 추가
//route start
app.use("/authCheck", require("./routes/auth"));
//route end
[ src / middleware / auth.js]
- front에서 headers에 넣은 토큰이 유효한 토큰인지 확인해주는 미들웨어
const jwt = require("jsonwebtoken");
const User = require("../models/User");
let auth = async (req, res, next) => {
//토큰을 request headers에서 가져오기
const authHeader = req.headers["authorization"];
//Bearer eyJhbGci.......
const token = authHeader && authHeader.split(" ")[1];
if (token === null) {
return res.sendStatus(401);
}
try {
//토큰이 유효한 토큰인지 확인
const decode = jwt.verify(token, process.env.JWT_SECRET); // 백앤드에서 설정한 SECRET키와 토큰에 있는 SECRET키와 같은지 확인
const user = await User.findOne({ userId: decode.userId });
if (!user) {
return res.status(400).send("없는 유저입니다.");
}
req.user = user; //토큰이 유효하면 req.user에 데이터를 넣어준다.
next();
} catch (error) {
next(error);
}
};
module.exports = auth;
[ routes / auth.js]
- 위에서 만들어놓은 미들웨어 auth를 넣어주었다. 미들웨어 부분에서 토큰이 유효하다면 req.user에 해당 유저데이터를 넣어주었기에 아래와 같이 json 형식으로 데이터를 front 쪽으로 보낼수 있다.
const express = require("express");
const auth = require("../middleware/auth");
const router = express.Router();
//토큰이 올바른 토큰인지 확인 -> auth미들웨어를 통해 확인 -> auth에서 유저데이터를 담아줌
router.get("/", auth, async (req, res, next) => {
return res.json({
userId: req.user.userId,
userName: req.user.userName,
userPhone: req.user.userPhone,
userEmail: req.user.userEmail,
userImage: req.user.userImage,
role: req.user.role,
});
});
module.exports = router;
- Frontend
[ src/ store / userSlice.tsx ]
- 백앤드에서 받아온 데이터를 리덕스 스토어에 넣어주는 부분
.addCase(authCheck.pending, (state) => {
state.isLoading = true;
})
.addCase(authCheck.fulfilled, (state, action) => {
state.isLoading = false;
state.userData = action.payload;
state.isAuth = true;
})
.addCase(authCheck.rejected, (state, action: any) => {
state.isLoading = false;
state.error = action.payload;
state.isAuth = false;
localStorage.removeItem("accessToken"); //토큰지워주기
})
[ 결과화면 ]
'React + Node.js' 카테고리의 다른 글
[MySchedule project] 9. 마이페이지 로직(1) - 조회, 업데이트 (1) | 2024.02.01 |
---|---|
[MySchedule project] 8. 인증에 의한 header, Route 로직 / 로그아웃 (2) | 2024.01.31 |
[MySchedule project] 6. JWT(json web token) / 로그인 로직(1) (2) | 2024.01.30 |
[MySchedule project] 5. backend - 회원가입 로직 (0) | 2024.01.25 |
[MySchedule project] 4. frontend - 회원가입 로직 (1) | 2024.01.25 |