1 유저 회원가입
1) RegisterScreen.js 생성
- SigninScreen.js파일을 복사해서 이름을 'RegisterScreen.js'로 변경한다.
2) RegisterScreen.js 수정
- Ctrl + F(비주얼스튜디오 기준) 단축키로 'SigninScreen'단어를 검색한 뒤 모두 'RegisterScreen'로 변경한다.
- 'signin'단어를 검색한 뒤 모두 'register'로 변경한다.
- 폼 부분을 변경하고, name항목을 DB목록에 추가한다.
import { register } from '../api'; import { getUserInfo, setUserInfo } from '../localStorage';
import { showLoading, hideLoading, showMessage } from '../utils';
const RegisterScreen = {
after_render: () => {
document.getElementById('register-form')
.addEventListener('submit', async(e) => {
e.preventDefault();
showLoading();
const data = await register({
name: document.getElementById('name').value, // 추가
email: document.getElementById('email').value,
password: document.getElementById('password').value,
});
hideLoading();
if(data.error){
showMessage(data.error);
}else{
setUserInfo(data);
document.location.hash = '/';
}
})
},
render: () => {
if(getUserInfo().name){
document.location.hash = '/';
}
return `
<div class="form-container">
<form id="register-form">
<ul class="form-items">
// <-- 추가 <li>
<h1> Create Account </h1>
</li>
<li>
<label for="name">Name</label>
<input type="name" name="name" id="name"/>
</li>
<li>
<label for="email">Email</label>
<input type="email" name="email" id="email"/>
</li>
<li>
<label for="password">Password</label>
<input type="password" name="password" id="password"/>
</li>
// <-- 추가 <li>
<label for="repassword">Re-Enter-Password</label>
<input type="password" name="repassword" id="repassword"/>
</li>
// 추가 --> <li>
<button type="submit" class="primary"> Register </button>
</li>
<li>
// <-- 수정 <div>
Already have an account?
<a href="/#/signin">Sign-In</a>
</div>
// 수정 --> </li>
</ul>
</form>
</div>
`;
},
};
export default RegisterScreen;
|
[ root\frontend\src\screens\RegisterScreen.js ]
3) api.js 추가
- 로그인 사용자 데이터를 POST방식으로 요청한 뒤에 결과를 반환하는 register( )함수를 추가한다.
export const register = async({name, email, password}) => { try{
const response = await axios({
url: `${apiUrl}/api/users/register`,
method: 'POST',
header: {
'Content-Type': 'application/json',
},
data: {
name,
email,
password,
},
});
if(response.statusText !== 'OK'){
throw new Error(response.data.message);
}
return response.data;
}catch(err){
console.log(err);
return { error: err.response.data.message || err.message }
}
}
|
[ root\frontend\src\api.js ]
4) index.js 추가
- /register 라우터를 추가한다.
// 중략...
import RegisterScreen from './screens/RegisterScreen';
const routes = {
'/': HomeScreen,
'/product/:id': ProductScreen,
'/cart/:id': CartScreen,
'/cart': CartScreen,
'/signin': SigninScreen,
'/register': RegisterScreen
};
for(let item in CartScreen){
// 중략...
|
[ root\frontend\src\api.js ]
5) userRouter.js 추가
- 사용자 등록폼에서 'submit'버튼을 클릭했을 때, 몽고DB 서버에 사용자가 입력한 폼데이터가 저장되어야 한다. 이와 관련된 기능은 backend\routers\userRouter.js가 담당한다.
//중략... userRouter.post( '/register',
expressAsyncHandler(async(req, res) => {
const user = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password,
});
const createUser = await user.save();
if(!createUser){
res.status(401).send({
message: 'Invalid Email or Password'
})
}else{
res.send({
_id: createUser._id,
name: createUser.name,
email: createUser.email,
isAdmin: createUser.isAdmin,
token: generateToken(createUser),
})
}
}) //expressHandler End
);
export default userRouter;
|
[ root\backend\routers\userRouter.js ]
2 계정 업데이트
1) ProfileScreen.js 생성
- ProfileScreen.js는 사용자 계정을 업데이트할 수 있는 기능을 담고있다.
import { update } from '../api'; import { getUserInfo, setUserInfo } from '../localStorage';
import { showLoading, hideLoading, showMessage } from '../utils';
const ProfileScreen = {
after_render: () => {
document
.getElementById('profile-form')
.addEventListener('submit', async(e) => {
e.preventDefault();
showLoading();
const data = await update({
name: document.getElementById('name').value,
email: document.getElementById('email').value,
password: document.getElementById('password').value,
});
hideLoading();
if(data.error){
showMessage(data.error);
}else{
setUserInfo(data);
document.location.hash = '/';
}
});
},
render: () => {
const { name, email } = getUserInfo();
return `
<div class="form-container">
<form id="profile-form">
<ul class="form-items">
<li>
<h1>User Profile</h1>
</li>
<li>
<label for="name">Name</label>
<input type="name" name="name" id="name" value="${name}" />
</li>
<li>
<label for="email">Email</label>
<input type="email" name="email" id="email" value="${email}" />
</li>
<li>
<label for="password">Password</label>
<input type="password" name="password" id="password" />
</li>
<li>
<button type="submit" class="primary">Update</button>
</li>
<li>
<button type="button" id="signout-button" >Sign Out</button>
</li>
</ul>
</form>
</div>
`;
},
};
export default ProfileScreen;
|
[ root\frontend\src\screens\ProfileScreen.js ]
2) api.js 추가
- 사용자가 정보를 업데이트 하는경우, 로컬 스토러지에 해당 정보를 저장하는 기능을 추가한다.
export const register = async({name, email, password}) => {
//중략...
}
export const update = async({name, email, password}) => { try{
const { _id, token } = getUserInfo();
const response = await axios({
url: `${apiUrl}/api/users/${_id}`,
method: 'PUT',
headers:{
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
data: {
name,
email,
password,
},
});
if(response.statusText !== 'OK'){
throw new Error(response.data.message);
}
return response.data;
}catch(err){
console.log(err);
return { error: err.response.data.message || err.message }
}
}
|
[ root\frontend\src\api.js ]
3) index.js 추가
- /profile 라우터를 추가한다.
//중략... import ProfileScreen from './screens/ProfileScreen'; //추가 const routes = {
'/' : HomeScreen,
'/product/:id':ProductScreen,
'/cart/:id': CartScreen,
'/cart': CartScreen,
'/signin': SigninScreen,
'/register': RegisterScreen,
'/profile': ProfileScreen, //추가
}
const router = async() => {
showLoading();
//중략... |
[ root\frontend\src\index.js ]
4) userRouter.js 추가
- userRouter.js는 유저가 업데이트한 데이터를 서버에 전달한다.
userRouter.post(
'/register',
//중략...
);
// <-- 추가 userRouter.put( '/:id',
isAuth,
expressAsyncHandler(async(req, res) => {
const user = await User.findById(req.params.id);
if(!user){
res.status(400).send({
message: 'User Not Found'
});
}else{
user.name = req.body.name || user.name;
user.email = req.body.email || user.email;
user.password = req.body.password || user.password;
const updateUser = await user.save();
res.send({
_id: updateUser._id,
name: updateUser.name,
email: updateUser.email,
isAdmin: updateUser.isAdmin,
token: generateToken(updateUser),
})
}
})
)
// 추가 -->
export default userRouter;
|
[ root\backend\routers\userRouter.js ]
3 Auth 인증
1) utils.js(backend) 추가
- header값에 authorization이 없다면, 에러를 반환하는 isAuth기능을 추가한다.
import jwt from 'jsonwebtoken'; import config from './config';
export const generateToken = (user) => {
return jwt.sign({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin
}, config.JWT_SECRET )
}
// <-- 추가 export const isAuth = (req, res, next) => { const bearerToken = req.headers.authorization;
if(!bearerToken){
res.status(401).send({ message: 'Token is not supplied'});
}else{
const token = bearerToken.slice( 7, bearerToken.length );
jwt.verify( token, config.JWT_SECRET, (err, data) => {
if(err){
res.status(401).send({ message: 'Invalid Token'});
}else{
req.user = data;
next();
}
})
}
}
// 추가 --> |
[ root\backend\utils.js ]
2) userRouter.js 추가
- utils.js에서 'isAuth'함수를 가져온 뒤, put()라우터의 미들웨어로 활용한다.
// 중략...
import { generateToken, isAuth } from '../utils'; // 추가
// 중략... userRouter.put(
'/:id',
isAuth, // 추가
expressAsyncHandler(async(req, res) => {
const user = await User.findById(req.params.id);
// 중략...
)
export default userRouter;
|
[ root\backend\utils.js ]
3) 테스트
- 아이디로 접속한 뒤에 이름을 변경해서 업데이트를 진행해보자.
- 업데이트가 성공적으로 반영되며, Request Headers에서 정상적으로 발급된 인증키를 확인할 수 있다.
4 로그아웃
1) ProfileScreen.js 추가
- after_render( )메서드에 로그아웃 버튼과 clearUser( )함수를 추가한다.
import { update } from '../api'; import { getUserInfo, setUserInfo, clearUser } from '../localStorage'; // clearUser 추가
import { showLoading, hideLoading, showMessage } from '../utils';
const ProfileScreen = {
after_render: () => {
document.getElementById('signout-button') // 추가...
.addEventListener('click', () => {
clearUser();
document.location.hash = '/';
})
document
.getElementById('profile-form') // 중략...
|
[ root\frontend\src\screens\ProfileScreen.js ]
2) localStorage.js 추가
- 로그아웃 버튼을 클릭하게 되면, 로컬 스토러지에 저장된 현재의 유저정보가 삭제된다.
// 중략... export const getUserInfo = () =>{ // 중략...
} // <-- 추가 export const clearUser = () => {
localStorage.removeItem('userInfo');
}
// 추가 -->
|
[ root\frontend\src\localStorage.js ]
3) 테스트
- 로그아웃 버튼을 클릭했을 때, 정상적으로 로그아웃이 진행된다.
'웹개발 자료실 > No프레임워크 쇼핑몰제작Code' 카테고리의 다른 글
E-commerce Vanilla JS [12편] 페이팔 SandBox 결제 (0) | 2021.12.16 |
---|---|
E-commerce Vanila JS [11편] 결제단계 (0) | 2021.12.13 |
E-commerce Vanila JS [9편] 로그인 인증(2) (0) | 2021.12.10 |
E-commerce Vanila JS [8편] 로그인 인증(1) (0) | 2021.12.10 |
E-commerce Vanila JS [7편] 몽고DB 연결 (0) | 2021.12.09 |
댓글