Auth.js 에 로그인하는 폼을 작성한다
이전에 구글과 깃허브 인증도 추가하였기 때문에 버튼을 만든다
const Auth = () => {
return (
<div>
<form>
<input name="email"
type="text"
placeholder="Email"
required
/>
<input name="password"
type="password"
placeholder="Password"
required
/>
<input type="submit" value="login" />
</form>
<div>
<button>Continue with Google</button>
<button>Continue with Github</button>
</div>
</div>
);
}
입력되는 값을 저장할 email과 password 변수를 생성한다.
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
form input에 입력된 값이 email, password에 저장되어야하므로 onChange 함수를 만들어 저장되도록 하고 그 값이 input에 보여지도록 value를 설정한다
두 변수에 동일한 함수를 사용하기 위해 event.target의 name, value를 가져온다. name은 작성중인 input의 name값이고 value는 input에 입력된 값이다. onChange에 name이 email인지 password인지 if문으로 판별하여 set함수를 통해 값을 setting한다
const onChange = (event) => {
const {target: {name, value}} = event;
if(name === "email"){
setEmail(value);
} else if(name === "password"){
setPassword(value);
}
}
...
<form>
<input name="email"
type="text"
placeholder="Email"
required
value={email}
onChange={onChange}
/>
<input name="password"
type="password"
placeholder="Password"
required
value={password}
onChange={onChange}
/>
...
로그인 기능을 작성하기 위해 firebase 비밀번호 기반 계정 생성를 살펴보면 계정을 생성하는 법과 로그인하는 법이 나와있다
만들어둔 폼으로 계정을 생성
const onSubmit = (event) => {
event.preventDefault();
try {
let data;
data = createUserWithEmailAndPassword(authService, email, password);
console.log(data);
} catch (error) {
console.log(error)
}
}
...
<form onSubmit={onSubmit}>
으로 변경하고 email과 password 값을 입력 후 버튼을 클릭하면 계정이 생성된다
생성된 계정은 firebese 인증/user에서 확인할 수 있다
(감상
진짜 감탄... 너무나 편리하다 계정 생성이 이렇게 함수 하나로 되어있다니.. 진짜 입력 후 버튼을 눌렀더니 계정이 생성되어있어서 너무 놀랐고 살짝 어이없었다 백엔드를 배워서 DB에 넣으려면 어떤 작업이 필요한지 알아서 더 놀란듯하다)
Persistence에서 사용자 정보 저장의 기본값이 local이다. 즉, 브라우저를 닫아도, 새로그침 해도 로그인된 사용자의 정보가 유지된다는 의미이다
App.js에서 currentUser를 확인
const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);
console.log(authService.currentUser)
setInterval(() => {
console.log(authService.currentUser)
}, 2000);
처음 서버를 실행했을 때는 User가 없지만, 잠시 후에 user의 정보가 출력된다
정보를 local로 저장했기 때문이다
=> firebase가 불러오는데 시간이 걸리기 때문에 처음에는 null이 출력된다. firebase가 불러와졌는지를 판단하는 기준이 currentUser가 된다
Auth의 onAuthStateChanged() 메소드를 이용하여 인증의 변화(생성, 로그인,로그아웃 등)를 감지한다. 감지가 된다면 firebase가 로딩됐다는 의미이다.
UseEffect를 사용하여 인증에 변화가 생기면 페이지가 변하도록 코드 작성
App.js
function App() {
const [init, setInit] = useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
authService.onAuthStateChanged((user) => {
if(user) {
setIsLoggedIn(true);
} else {
setIsLoggedIn(false)
}
setInit(true);
});
}, []);
return (
<>
{init ? <AppRouter isLoggedIn={isLoggedIn}/> : "Initializing..."}
<footer>© {new Date().getFullYear()} Nwitter</footer>
</>
);
}
로그인 코딩
계정 생성할 때 이미 존재하는 id를 입력하면 다음과 같은 에러가 발생한다
❗ 이전 코드 수정
createUserWithEmailAndPassword() 와 signInWithEmailAndPassword()은 Promise를 반환하기 때문에 async,await를 사용해야한다
Auth.js
const onSubmit = async (event) => {
event.preventDefault();
try{
let data;
if (newAccount) {
data = await createUserWithEmailAndPassword(authService,email,password);
} else {
data = await signInWithEmailAndPassword(authService,email, password);
}
console.log(data);
} catch(error){
console.log(error)
}
}
경고문구를 표시하기 위해 error 생성하여 에러 발생하면 값 설정
Auth.js
const [error, setError] = useState("");
...
const onSubmit = async (event) => {
event.preventDefault();
try{
let data;
if (newAccount) {
data = await createUserWithEmailAndPassword(authService,email,password);
} else {
data = await signInWithEmailAndPassword(authService,email, password);
}
console.log(data);
} catch(error){
setError(error.message)
}
}
...
<p>{error}</p>
const toggleAccount = () => setNewAccount((prev) => ! prev);
...
<input type="submit" value={newAccount ? "계정 생성" : "로그인"}/>
<p>{error}</p>
</form>
<span onClick={toggleAccount}>
{newAccount ? "Log in." : "Create Account"}
</span>
실행해보면 오류가 발생하면 다음과같이 오류가 출력되고
로그인되면 Home으로 이동한다.