Firebase์์ ์ฌ์ฉ์ ๊ด๋ฆฌ
Google์ ํ์ธ ๊ณต๋์ฒด๋ฅผ ์ํ ์ธ์ข ์ ํ๋ฑ์ ์ถ๊ตฌํ๊ธฐ ์ํด ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค. ์์ธํ ์์๋ณด๊ธฐ ์ด ํ์ด์ง๋ Cloud Translation API๋ฅผ ํตํด ๋ฒ์ญ๋์์ต๋๋ค. Switch to English ์๊ฒฌ ๋ณด๋ด๊ธฐ Firebase์์ ์ฌ์ฉ
firebase.google.com
๋ณด์์ ์ํด ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ์ ์ฃผ๊ธฐ์ ์ผ๋ก ํด์ผ ํฉ๋๋ค. ๐
๊ทธ๋ผ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ์ ๊ตฌํํ๊ฒ ์ต๋๋ค!
01. ์ปดํฌ๋ํธ ๊ตฌํ
์ฌ๋ฌ ๊ฐ์ input ๊ตฌํ์ ์์ฑํ ๊ธ์ ๋๋ค.
[React/JS] useState - ์ฌ๋ฌ ๊ฐ์ input ์ํ ๊ด๋ฆฌํ๊ธฐ
์ ๋ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ์ ์์๋ก ๊ตฌํํ๊ฒ ์ต๋๋ค! ์ฐ์ ์ต์ข ์ฝ๋์ ๋๋ค. ๐ import * as React from "react"; export default function PasswordChange() { // input ์ปดํฌ๋ํธ์ id ์ ์ธ // ํ์ฌ ๋น๋ฐ๋ฒํธ const CURRENT_PASSWORD =
avoc-o-d.tistory.com
๊ธฐ๋ฅ ๊ตฌํ์ ํ์ํ ๋ถ๋ถ๋ง ๊ฐ์ ธ์์ต๋๋ค. ๐ (์ฐธ๊ณ . ๋ฉํ ๋ฆฌ์ผ ๋์์ธ ์ปดํฌ๋ํธ ์ฌ์ฉ)
// id
const CURRENT_PASSWORD = "currentPassword";
const NEW_PASSWORD = "newPassword";
const NEW_PASSWORD_CONFIRM = "newPasswordConfirm";
// input ๋ณ์
const [inputs, setInputs] = React.useState({
currentPassword: "", // ํ์ฌ ๋น๋ฐ๋ฒํธ
newPassword: "", // ์ ๋น๋ฐ๋ฒํธ
newPasswordConfirm: "", // ์ ๋น๋ฐ๋ฒํธ ํ์ธ
});
const { currentPassword, newPassword, newPasswordConfirm } = inputs; // ๋น๊ตฌ์กฐํ ํ ๋น์ ํตํด ๊ฐ ์ถ์ถ
// ๋น๋ฐ๋ฒํธ ์
๋ ฅ
const handlePasswordInput = (event) => {
const { id, value } = event.target;
setInputs({
...inputs, // ๊ธฐ์กด์ input ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํ ๋ค
[id]: value, // name ํค๋ฅผ ๊ฐ์ง ๊ฐ์ value ๋ก ์ค์
});
};
// ๋น๋ฐ๋ฒํธ ํผ ์ ์ถ ํจ์
async function handleSubmit(event) {
...
}
// ๋ณ๊ฒฝํ๊ธฐ ๋ฒํผ ํ์ฑํ
const [isDisabled, setIsDisabled] = React.useState(true);
React.useEffect(() => {
if (
currentPassword === "" ||
newPassword === "" ||
newPasswordConfirm === ""
)
setIsDisabled(true);
else setIsDisabled(false);
}, [currentPassword, newPassword, newPasswordConfirm]);
return(
// ํ์ฌ ๋น๋ฐ๋ฒํธ
<TextField
type="password"
id={CURRENT_PASSWORD}
placeholder="ํ์ฌ ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์."
variant="outlined"
value={currentPassword}
onChange={handlePasswordInput}
/>
// ์ ๋น๋ฐ๋ฒํธ
<TextField
type="password"
id={NEW_PASSWORD}
placeholder="์ ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์."
variant="outlined"
value={newPassword}
onChange={handlePasswordInput}
/>
// ์ ๋น๋ฐ๋ฒํธ ํ์ธ
<TextField
type="password"
id={NEW_PASSWORD_CONFIRM}
placeholder="์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ค์ ์
๋ ฅํด์ฃผ์ธ์."
variant="outlined"
value={newPasswordConfirm}
onChange={handlePasswordInput}
/>
<Button
onClick={handleSubmit}
disabled={isDisabled}
>
๋ณ๊ฒฝํ๊ธฐ
</Button>
)
๐ ์ฐธ๊ณ ๋ก input ๋ถ๋ถ์ด ์ค๋ณต๋๋ ์ปดํฌ๋ํธํ ํด์ ํธ์ถํ๋ฉด ๋๋ ๊ฑฐ ์๋์ง.. ์๋ฌธ์ ๊ฐ์ง์ จ๋ค๋ฉด ์๋ ๊ธ์ ์ฐธ๊ณ ํด์ฃผ์๊ธฐ ๋ฐ๋๋๋ค.๐
[React/JS] input์์ ํ ๊ธ์ ์ ๋ ฅ ํ focus๋ฅผ ์๋ ํ์
00. input์์ ํ ๊ธ์ ์ ๋ ฅ ํ focus๋ฅผ ์๋ ํ์ input ํ๊ทธ์์ ํ ๊ธ์๋ฅผ ์ ๋ ฅํ์๋ง์ input์ focus๊ฐ ์ฌ๋ผ์ง๋ ํ์์ด ๋ฐ์ํฉ๋๋ค... ๊ทธ๋ฌ๋ฉด, ํ ๊ธ์ ์น๊ณ ๋ค์ ์ ๋ ฅ์ฐฝ ํด๋ฆญํ๊ณ ,, ์น๊ณ ํด๋ฆญํ๊ณ ,,
avoc-o-d.tistory.com
02. ํ์ฌ ๋น๋ฐ๋ฒํธ ์ ๋ ฅ ์ ์ด (์ฌ๋ก๊ทธ์ธ)
๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ์ ๋ณด์์ ๋งค์ฐ ๋ฏผ๊ฐํ ๋ถ๋ถ์ด์ฃ .
๋ฐ๋ผ์, ๊ฐ์ฅ ์ต๊ทผ์ ๋ก๊ทธ์ธ์ด ๋์ด์ผ ํฉ๋๋ค. ์ฆ, ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ํ์ฌ ๋น๋ฐ๋ฒํธ๋ก ์ฌ๋ก๊ทธ์ธ์ ํด์ผ ํฉ๋๋ค.
import {
auth,
EmailAuthProvider,
reauthenticateWithCredential,
} from "../../service/firebase";
// ๋น๋ฐ๋ฒํธ ํผ ์ ์ถ ํจ์
async function handleSubmit(event) {
const user = auth.currentUser; // ํ์ฌ ์ฌ์ฉ์์ ์ ๋ณด์ ์ ๊ทผ
// 01. ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ํ์ฌ ๋น๋ฐ๋ฒํธ๋ก credential ๋ฐ๊ธ
const credential = EmailAuthProvider.credential(
user.email,
currentPassword
);
// 02. ๋ฐ๊ธ๋ฐ์ credential๋ก ์ฌ๋ก๊ทธ์ธ
// => ์์ธ์ฒ๋ฆฌ ) ๋ง์ฝ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ํ์ฌ ๋น๋ฐ๋ฒํธ๊ฐ ํ๋ ธ๋ค๋ฉด? ์๋ฌ ๋ฉ์ธ์ง
await reauthenticateWithCredential(user, credential)
.then(() => {
// ๋ก๊ทธ์ธ ์ฑ๊ณต
})
.catch((error) => {
// ๋ก๊ทธ์ธ ์คํจ
});
}
์์ฒ๋ผ ํ์ฌ ๋น๋ฐ๋ฒํธ๋ฅผ ์๋ชป ์ ๋ ฅํ์ ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ๊ฒ ์ต๋๋ค!
๐ ์ฐธ๊ณ : error๋ฅผ ์ฝ์๋ก ์ฐ์ผ๋ฉด, auth/wrong-password ์ฒ๋ผ ์๋ฌ์ฝ๋๊ฐ ๋ ๋ผ์ต๋๋ค.
์ด๋ฅผ ์ด์ฉํ์ฌ "auth/wrong-password" ๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ์, "๋น๋ฐ๋ฒํธ๊ฐ ์๋ชป๋์์ต๋๋ค." ๋ก error ๋ฉ์ธ์ง๋ฅผ ๋ณ๊ฒฝํด์ฃผ๋๋ก ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ์ฌ ๋น๋ฐ๋ฒํธ input ์ปดํฌ๋ํธ๋ฅผ error ์ฒ๋ฆฌํด์ค๋๋ค.
// ํ์ฌ ๋น๋ฐ๋ฒํธ error log
const [currentPasswordLog, setCurrentPasswordLog] = React.useState(false);
// ๋น๋ฐ๋ฒํธ ํผ ์ ์ถ ํจ์
async function handleSubmit(event) {
...
// 02. ๋ฐ๊ธ๋ฐ์ credential๋ก ์ฌ๋ก๊ทธ์ธ
// => ์์ธ์ฒ๋ฆฌ ) ๋ง์ฝ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ํ์ฌ ๋น๋ฐ๋ฒํธ๊ฐ ํ๋ ธ๋ค๋ฉด? ์๋ฌ ๋ฉ์ธ์ง
await reauthenticateWithCredential(user, credential)
.then(() => {
// ๋ก๊ทธ์ธ ์ฑ๊ณต
})
.catch((error) => {
handleAuthError(error.code); // auth/wrong-password => "๋น๋ฐ๋ฒํธ๊ฐ ์๋ชป๋์์ต๋๋ค."
switch (error.code) {
case "auth/wrong-password": { // auth/wrong-password => ํ์ฌ ๋น๋ฐ๋ฒํธ input error
return setCurrentPasswordLog(true);
}
}
});
}
03. ์ ๋น๋ฐ๋ฒํธ, ์ ๋น๋ฐ๋ฒํธ ํ์ธ ์ ๋ ฅ ์ ์ด (์ ๋ ฅ๊ฐ ์ผ์น ์ฌ๋ถ)
์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ์ ๋น๋ฐ๋ฒํธ์ ์ ๋น๋ฐ๋ฒํธ ํ์ธ์ด ์ผ์นํ์ง ํ์ธํฉ๋๋ค.
// ์ ๋น๋ฐ๋ฒํธ ํ์ธ error log
const [newPasswordConfirmLog, setNewPasswordConfirmLog] = React.useState(false);
// 03. ์ ๋น๋ฐ๋ฒํธ, ์ ๋น๋ฐ๋ฒํธ ํ์ธ ์ผ์นํ๋์ง ๊ฒ์ฌ
function validatePassword() {
let isValid = true;
if (
newPassword !== "" &&
newPasswordConfirm !== "" &&
newPassword !== newPasswordConfirm
) {
isValid = false;
handleAuthError("invalid-password"); // invalid-password => "๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค."
}
// ์ผ์นํ์ง ์์ ๊ฒฝ์ฐ => ์ ๋น๋ฐ๋ฒํธ ํ์ธ input error
setNewPasswordConfirmLog(!isValid);
return isValid;
}
// ๋น๋ฐ๋ฒํธ ํผ ์ ์ถ ํจ์
async function handleSubmit(event) {
...
// 03. ์ ๋น๋ฐ๋ฒํธ, ํ์ธ ๊ฒ์ฌ
if (!validatePassword()) return;
}
04. ์ ๋น๋ฐ๋ฒํธ ๋ณด์ ์ ์ด (๋ณด์ ์ ๋ ๊ด๋ฆฌ)
์ ๋น๋ฐ๋ฒํธ ์ญ์ ๋ณด์์ ์ํด ์์ ํ ๋น๋ฐ๋ฒํธ์ฌ์ผ๊ฒ ์ฃ ? ๐
import {
...
updatePassword
} from "../../service/firebase";
// ์ ๋น๋ฐ๋ฒํธ error log
const [newPasswordLog, setNewPasswordLog] = React.useState(false);
// ๋น๋ฐ๋ฒํธ ํผ ์ ์ถ ํจ์
async function handleSubmit(event) {
...
// 04. ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ
await updatePassword(user, newPassword)
.then(() => {
// ๋ณ๊ฒฝ ์ฑ๊ณต
})
.catch((error) => {
// ๋ณ๊ฒฝ ์คํจ
handleAuthError(error.code); // auth/weak-password => "์์ ํ์ง ์์ ๋น๋ฐ๋ฒํธ์
๋๋ค. ๋ค๋ฅธ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ฉํด ์ฃผ์ธ์."
switch (error.code) {
case "auth/weak-password": { // auth/weak-password => ์ ๋น๋ฐ๋ฒํธ input error
return setNewPasswordLog(true);
}
}
});
}
05. ๋ณ๊ฒฝ ์๋ฃ
์ฑ๊ณต์ ์ผ๋ก ๋ณ๊ฒฝ์ด ์๋ฃ๋์๋ค๋ฉด, ์ค๋ต๋ฐ๊ฐ์ ์ปดํฌ๋ํธ๋ก ์ฒ๋ฆฌํด์ฃผ๋ฉด ๊ตฟ~!
React Snackbar component - Material UI
Snackbars provide brief notifications. The component is also known as a toast.
mui.com
์ํํซ ๐๐
'๐ป My Work > ๐ฅ React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React/JS] arrow function (0) | 2023.01.17 |
---|---|
[React/JS] ํ์ด์ง URL ๋ณต์ฌํ๊ธฐ - ํ ์คํธ ๋ณต์ฌ Clipboard API (0) | 2023.01.12 |
[React/JS] useState - ์ฌ๋ฌ ๊ฐ์ input ์ํ ๊ด๋ฆฌํ๊ธฐ (0) | 2022.12.15 |
[React/JS] Firebase - ๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ, ๋น๋ฐ๋ฒํธ ์ฌ์ค์ sendPasswordResetEmail (0) | 2022.11.15 |
[React/JS] ์์๊ฐ Object์ธ ๋ฐฐ์ด์ ์ค๋ณต ์ ๊ฑฐํ๊ธฐ (0) | 2022.11.08 |