회원가입 완료 후 회원가입된 아이디 비밀번호로 로그인이 성공하면 대쉬보드 페이지로 넘어가는 서비스를 구현해보자.
먼저 SignupComponent와 LoginComponent에 useEffect로 해당 컴포넌트에 처음 들어갈 때 userState를 초기화하는 구문을 넣어준다. 이 구문을 넣지 않으면 회원가입에서 진행했던 내용들이 그대로 로그인 화면에도 쓰이게 된다.
useEffect(()=> {
dispatch({type: actionTypesUser.USER_INIT})
},[])
[cate].tsx에서 SignupComponent에 전달했던 값과 똑같은 값을 LoginComponent에 넘겨준다.
[cate].tsx
<LoginComponent
userChangeHandler={userChangeHandler} // 로그인에 props로 Handler함수를 보낸다.
userState={userState} /> : ""}
로그인 화면을 다음과같이 구성해준다.
LoginComponent.tsx
import type { NextPage } from 'next'
import { actionTypesUser, UserState } from "../../store/interfaces/";
import { useEffect } from 'react'
import { useDispatch } from 'react-redux';
import Link from 'next/link'
interface Props {
userChangeHandler : (event : any) => void;
userState : UserState;
}
const Login:NextPage<Props> = ({userChangeHandler,userState}) => {
const dispatch = useDispatch();
useEffect(()=> {
dispatch({type: actionTypesUser.USER_INIT});
},[])
const LoginHandler = (event : any) => {
event.preventDefault();
}
return (
<div className='login'>
<form onSubmit={LoginHandler}>
<div>
<input
name="id"
type="text"
placeholder="Enter ID"
onChange={userChangeHandler} />
</div>
<div>
<input
name="pw"
type="password"
placeholder="Enter PW"
onChange={userChangeHandler} />
</div>
<div>
<button
type="submit">
Login
</button>
</div>
<Link href={`/auth/signup`}>
<a> 회원가입 화면으로 가기 </a>
</Link>
</form>
</div>
)
}
export default Login
아이디 입력창과 비밀번호 입력창, 로그인 버튼과 Link를 사용해 화면을 구성했다. 회원가입에서 이미 다뤘던 내용들이라 자세한 설명은 하지 않겠다.
next/link에 관한 자세한 내용은 다음 링크에서 확인할 수 있다.
https://nextjs.org/docs/api-reference/next/link
next/link | Next.js
Enable client-side transitions between routes with the built-in Link component.
nextjs.org
화면을 확인해보면
이제 로그인 버튼을 눌렀을 경우 DB를 조회하고 해당 아이디 비밀번호가 올바르면 로그인 성공 메세지가 뜨게 할 것이다.
먼저 로그인에 필요한 액트, 타입, 리듀서, 액션을 만들어주자.
userAct.interfaces.ts
(...)
USER_LOGIN = "USER_LOGIN", // 로그인
(...)
export type ActionsUser = UserInit | UserState | UserInfo | UserIdDuplicate
| UserEmailDuplicate | UserEmailSend | UserEmailCert
| UserSignup | UserLogin
(...)
export interface UserLogin {
type : actionTypesUser.USER_LOGIN;
payload : any;
}
user_reducer.ts
case actionTypesUser.USER_LOGIN:
return {
...state, data : action.payload
}
user_action.ts
export async function userLogin (userInfo : UserInfo) {
const request = Axios.post('/api/user/login',{userInfo})
.then(response => response.data)
return {
type : actionTypesUser.USER_LOGIN,
payload: request
}
}
그다음 LoginHandler 함수를 다음과 같이 조건식을 세워서 만든다.
LoginComponent.tsx
const LoginHandler = (event : any) => {
event.preventdefault();
dispatch(userLogin(userState.userInfo)).then((req : any) => {
if(req.payload.result === "success") { // 로그인 성공 시
alert('로그인 성공입니다.');
}
else if(req.payload.result === "IdFailed") { // 아이디가 없을 경우
alert('존재하지 않는 아이디입니다.');
}else if(req.payload.result === "PwFailed"){ // 비밀번호가 틀릴경우
alert('비밀번호가 틀렸습니다.');
}else { // 그 외의 경우
alert('로그인 실패입니다.');
}
})
}
이제 프론트에서 할 일은 끝났다. 백엔드로 넘어가보자. 먼저 컨트롤러 부분에 login Post데코레이터를 만들어준다.
user.controller.ts
@Post('login')
async logIn(@Res({ passthrough: true}) res : any, @Req() req : any) {
return await this.userService.logIn(req.body.userInfo,res);
}
user.service.ts
async logIn(userInfo : CreateUserDto, res : any) {
try {
const userOne = await this.userModel.findOne({id : userInfo.id});
if(userOne) { // ID가 존재할 경우
const result = await bcrypt.compare(userInfo.pw,userOne.pw);
if(result) { // 비밀번호가 일치할 경우
res.cookie('isLogined',userInfo.id, {path: '/', expires: new Date(Date.now()+86400000)});
return { result : "success"};
}
else { // 비밀번호가 틀릴 경우
return { result : "PwFailed"};
}
}else { // ID가 없을 경우
return { result : 'IdFailed'};
}
}catch(e) {
return false;
}
}
이제 화면에서 로그인이 성공했을 때 쿠키가 제대로 생기는지 확인해보자.
- 존재하지 않는 ID일 경우
- 비밀번호가 틀릴 경우
- 로그인이 성공할 경우
쿠키까지 확인 :
로그인 성공 시 쿠키가 잘 생성되는것을 확인했다.
마지막으로 로그인이 완료되면 넘어갈 페이지인 대시보드 페이지를 만들어보자.
/pages/dashboard.tsx
import type { NextPage } from 'next'
import Link from 'next/link'
const Dashboard:NextPage = () => {
return (
<div className='dashboard'>
Dashboard
</div>
)
}
export default Dashboard
LoginComponent.tsx
const LoginHandler = (event : any) => {
event.preventDefault();
dispatch(userLogin(userState.userInfo)).then((req : any) => {
if(req.payload.result === "success") { // 로그인 성공 시
alert('로그인 성공입니다.');
router.push(`/dashboard`)
}
else if(req.payload.result === "IdFailed") { // 아이디가 없을 경우
alert('존재하지 않는 아이디입니다.');
}else if(req.payload.result === "PwFailed"){ // 비밀번호가 틀릴경우
alert('비밀번호가 틀렸습니다.');
}else { // 그 외의 경우
alert('로그인 실패입니다.');
}
})
}
router.push를 이용해 성공시 대쉬보드 페이지로 넘어가게끔 했다.
'Nest - Next' 카테고리의 다른 글
Nest - Next | n2server | Passport , JWT | decode in Client (0) | 2021.10.27 |
---|---|
Nest - Next | n2server | Passport , JWT (0) | 2021.10.26 |
Nest - Next | n2server | Signup | Complete (0) | 2021.10.25 |
Nest - Next | n2server | Signup | Address (0) | 2021.10.22 |
Nest - Next | n2server | Signup | Email Send(3) (0) | 2021.10.20 |