카테고리 없음
[React] 자동로그인 설정(redux-toolkit,tailwind사용)
maggieH
2025. 4. 4. 22:42
redux-toolkit을 활용한 자동로그인 설정하는 튜토리얼이다.
기본적인 구조는 생략하고 메인이 되는 페이지 구현 및 함수만 간략하게 정리해보았다.
1.로그인을 진행할 비동기함수를 설정하고, responsive값이 true일때 해당 유저 정보를 요청하여 initailState값에 넣는다.
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import api from "../../common/api";
export const adminLogin = createAsyncThunk("login/login", async (params) => {
console.log(params)
const res = await api.post("/admin/login", params);
return res.data
});
const initialState = {
state: null,
adminNotauto: [],
};
const adminloginSlice = createSlice({
name: "로그인",
initialState,
extraReducers: {
[adminLogin.fulfilled]: (state, action) => {
state.status = "success";
state.adminNotauto = action.payload.admin;
},
},
});
export default adminloginSlice.reducer;
2.로그인을 진행할 페이지에 ui를 그려주고,
input으로 userId,password를 onChange함수로 받는다.
자동로그인 input type checkbox의 경우 useRef로 잡고, 해당 checkbox의 current.checked값을 submit 할 부분의 조건식으로 활용하여 window 내장함수인 localStorage에 담는다.
import React, { useState, useRef, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import {
adminLogin,
} from "../../../features/admin/adminloginSlice";
import { toast } from "react-toastify";
import toastCommonProps from "../../../common/Toast";
const SignIn = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
const [loginInput, setLoginInput] = useState({
adminId: "",
pass: "",
});
const checkRef = useRef()
const onChangeLogin = (e) => {
const { name, value } = e.target;
setLoginInput({ ...loginInput, [name]: value });
};
const Loginin = async () => {
const response = await dispatch(adminLogin(loginInput)).unwrap();
try {
if (response.ok === true) {
if(checkRef.current.checked){
window.localStorage.setItem("admin", JSON.stringify(response.admin));
}else{
window.localStorage.removeItem("admin")
}
toast(<p>로그인 성공</p>, toastCommonProps("top-right", "toast_alert"));
navigate("/admin");
} else {
toast(<p>아이디와 비밀번호를 다시 확인해주세요.</p>, toastCommonProps("top-right", "toast_alert"));
}
} catch (error) {
console.log(error);
}
};
return (
<div className="flex items-center">
<div className="w-full max-w-lg bg-gray_100 rounded-[24px] shadow-md p-14">
<div>
<label htmlFor="adminId" className="text-caption_2 text-gray_10">
아이디
</label>
<input
id="adminId"
type="text"
name="adminId"
value={loginInput.adminId}
onChange={onChangeLogin}
placeholder="아이디를 입력하세요"
className="w-full p-[12px] border rounded-md focus:outline-none focus:ring-2 focus:ring-primary_100 mb-4 text-caption_2"
onKeyPress={(e) => {
if (e.key === "Enter") Loginin();
}}
/>
<label htmlFor="adminPass" className="text-caption_2 text-gray_10">
비밀번호
</label>
<input
id ="adminPass"
type="password"
value={loginInput.pass}
onChange={onChangeLogin}
autoComplete="one-time-code"
name="pass"
placeholder="비밀번호를 입력하세요"
className="w-full p-[12px] border rounded-md focus:outline-none focus:ring-2 font-mono focus:ring-primary_100 text-caption_2"
onKeyPress={(e) => {
if (e.key === "Enter") Loginin();
}}
/>
<div className="pt-4 text-caption_2 text-gray_10 flex items-center gap-x-2">
<input type="checkbox" id="check" ref={checkRef}/>
<label htmlFor="check">자동로그인</label>
</div>
<button
onClick={Loginin}
className={
"mt-4 w-full text-center border cursor-pointer rounded-md bg-primary_100 text-sm font-semibold py-4 text-gray_100"
}
>로그인
</button>
</div>
</div>
</div>
);
};
export default SignIn;
3. user가 사용 페이지에 진입했을때 자동로그인 한경우, 일반로그인한 경우 user가 비거나 비지않았을 경우의 수를 삼항다항식에 담아, useEffect로 페이지 최초 출력시 혹은 새로고침시 페이지로 이동하도록 로직을 작성하였다.
import React, { useEffect,useState } from "react";
import { useNavigate } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
const Admin = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
//notautouser:일반로그인 autouser:자동로그인
const autouser = JSON.parse(window.localStorage.getItem("admin"));
const notautouser = useSelector((state) => state.adminLogin.adminNotauto);
const user = autouser === null && notautouser.length === 0 ?"nouser"
:autouser !== null ? autouser : notautouser ;
useEffect(() => {
if(user !== "nouser"){
//user가 자동로그인이거나, 자동로그인이 아닐때 출력
}else{
//페이지내에 user값이 없을때 페이지 signin으로 이동
navigate("/admin/signin")
}
}, [dispatch,navigate]);
[...]