회원가입 로그인 할 때 DB 비교해서 성공 / 실패 로직 만들기
routers - user - user.controller.js
기존 코드
let login_check = async (req,res)=>{
let userid = req.body.userid;
let userpw = req.body.userpw;
let result = await User.findOne({
where:{userid, userpw}
})
console.log(result)
req.session.uid = userid;
req.session.isLogin = true;
req.session.save(()=>{
res.redirect('/');
})
}
result 콘솔로그 확인
result = user가 login 할 때 입력한 userid, pw값을 기반으로 DB에서 찾아온 값 (성공or실패)
userid, userpw 값을 잘 입력했다면 아래와 같은 console.log(result)가 나온다.
User {
dataValues: {
id: 2,
userid: '아이디당',
userpw: '1234',
username: '이름이당',
gender: true,
userimage: null,
userdt: 2021-05-10T00:31:53.000Z
},
_previousDataValues: {
id: 2,
userid: '아이디당',
userpw: '1234',
username: '이름이당',
gender: true,
userimage: null,
userdt: 2021-05-10T00:31:53.000Z
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [
'id',
'userid',
'userpw',
'username',
'gender',
'userimage',
'userdt'
]
},
isNewRecord: false
}
로그인 시 아이디, 비번이 DB와 다르다면
== NULL
요 부분을 사용해서 if 함수 만들어서 로그인 성공/실패 만들기
let login_check = async (req,res)=>{
let userid = req.body.userid;
let userpw = req.body.userpw;
let result = await User.findOne({
where:{userid, userpw}
})
console.log(result)
//로그인 실패
if(result ==null){
res.redirect('/user/login'); // login page로 다시 보내버리기
}else{
//로그인 성공
req.session.uid = userid;
req.session.isLogin = true;
req.session.save(()=>{
res.redirect('/');
})
}
}
만약 로그인 실패시 팝업창 띄우기
get값으로 flag값 0 으로 보내기
if(result ==null){
res.redirect('/user/login?flag=0');
로그인 시 아이디, 비번 잘못 쳤을 때 위의 url이 뜨는지 확인
로그인 -> login_check - >성공 (main page)
- > 실패 (login?flag=0) ---> login은 지금 flag 받는 부분이 없을 것 ---> 추가해주기
let login = (req,res)=>{
let flag = req.query.flag;
res.render('./user/login.html',{flag});
}
이 flag 값을 login.html 로 보내기
views- login.html
조건문 걸어서 경고창 나올 수 있게끔
login.html <br/>
<form method = "post" action ="/user/login_check">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" id ="userid" name = "userid">
</td>
</tr>
<tr>
<td>비밀번호 </td>
<td>
<input type ="text" id ="userid" name = "userpw">
</td>
</tr>
</table>
<input type ="submit" value = "로그인하기">
</form>
{% if flag == '0' %}
<script type = "text/javascript">
alert('아이디와 패스워드를 확인해주세요');
</script>
{% endif %}
server on -> 잘못된 아이디or 비번으로 로그인 시 아래와 같은 팝업창나옴 -> 확인 누르면 -> 다시 login으로 redirect
스타일 바꾸기 (요즘 트렌드)
views - login.html
login.html <br/>
<form method = "post" action ="/user/login_check">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" id ="userid" name = "userid">
</td>
</tr>
<tr>
<td>비밀번호 </td>
<td>
<input type ="text" id ="userpw" name = "userpw">
</td>
</tr>
</table>
<input type ="submit" value = "로그인하기">
</form>
{% if flag == '0' %}
<script type = "text/javascript">
// alert('아이디와 패스워드를 확인해주세요');
const id = document.querySelector('#userid');
const pw = document.querySelector('#userpw');
id.setAttribute('style', 'background:lightsalmon');
pw.setAttribute('style', 'background:lightsalmon');
id.addEventListener('focus', ()=>{
id.setAttribute('style', 'background:#fff');
})
pw.addEventListener('focus', ()=>{
pw.setAttribute('style', 'background:#fff');
})
</script>
{% endif %}
======================================2교시===================================
로그인 성공 시 하나 더 기능 추가하기
회원정보 볼 수 있는 페이지 info
기존 views - index.html
{% if isLogin %}
{{userid}}님 환영합니다. <a href = "/user/logout" > 돌아가기 </a>
{% else %}
<a href="/user/login" >로그인</a>
<a href="/user/join" >회원가입</a>
{% endif %}
{% if isLogin %}
{{userid}}님 환영합니다. <br/>
<a href = "/user/logout" > 로그아웃 </a> //돌아가기 -> 로그아웃 이름 수정
<a href = "/user/info">회원 정보</a> //추가
{% else %}
<a href="/user/login" >로그인</a>
<a href="/user/join" >회원가입</a>
{% endif %}
회원 정보 클릭하면
routers-user - user.controller.js
let info = async (req,res)=>{
let result = await User.findAll({});
res.render('./user/info.html', {
result,
})
// res.json({
// result,
// })
}
어제 쓴 json 주석처리하고 다시 nunjucks 사용하는 render로 수정 !
서버 키고 다시 실행해보면 ↓↓↓
* 날짜 바꾸기
애초에 가지고 올 때 날짜형태 변환해서 가져오기 -> models - user.js 파일에서 ! - userdt 부분 코드 추가
( select 로 매번 가져오기는 번거로움)
1. 코드 수정
userdt:{
type:Sequelize.DATEONLY, // 수정
allowNull:false,
defaultValue:Sequelize.NOW,
get: function(){ // 추 ㄱ ㅏ
return moment(this.getDataValue('userdt')).format('YYYY-MM-DD') //field명
}
}
moment() -> method 이다.
this.getDataValue('userdt') - class 활용
format ('YY~ ') 으로
2. npm 터미널 'moment' 다운
패키지 다운받아야 moment 사용할 수 있다.
: npm install moment
3. user.js 파일 코드 수정 (다운 받은걸 가져오기 )
const moment = require('moment');
전체 user.js
const Sequelize = require('sequelize') // Class
const moment = require('moment');
module.exports = class User extends Sequelize.Model{
static init(sequelize){
return super.init({
userid:{
type:Sequelize.STRING(20),
allowNull:false,
unique:true,
},
userpw:{
type:Sequelize.STRING(20),
allowNull:false,
},
username:{
type:Sequelize.STRING(20),
allowNull:false,
},
gender:{
type:Sequelize.BOOLEAN,
allowNull:false,
},
userimage:{
type:Sequelize.STRING(100),
allowNull:true,
},
userdt:{
type:Sequelize.DATE,
allowNull:false,
defaultValue:Sequelize.NOW,
get: function(){
return moment(this.getDataValue('userdt')).format('YYYY-MM-DD') //field명
}
}
},{
sequelize,
timestamps:false,
underscored:false,
paranoid:false,
modelName:"User",
tableName:"users0510",
charset:"utf8",
collate:"utf8_general_ci",
})
}
static associate (db){}
}
4. 테이블 껐다가 다시 키기
server.js -
sequelize.sync({force:true})
true - 덮어쓰기로 table 다시 생성
5. 회원가입 다시 진행 해서 2~3개 row 만들기
* 주의 사항 ! table 한 번 만들었으면 위의 force:true -> false 로 바꾸기 !
(안 그러면 계속 덮어씌여져서 회원가입을 계속해도 id 1개 (가장 마지막에 만든) 만 나옴)
==============================image upload 부분 =================================
회원가입 page 봅시다.
파일 업로드 하는거 배우기 !
코드 길이는 짧으나 쪼곰 어려울 수 있음
image를 받을 수 있는 공간 만들기
1. views = join.html 에 이미지 업로드하는 공간 만들기
<tr>
<td>성별</td>
<td>
<input type ="radio" name ="gender" value="0" checked >남자
<input type ="radio" name ="gender" value="1" >여자
</td>
</tr>
<tr>
<td>이미지</td>
<td><input type="file" name="img"></td>
</tr>
요렇게 넣기
아래처럼 어떤걸 받을 지 정할 수 있지만 일단 우리는 작동 먼저 하려고 안쓸 것 !
<tr>
<td>이미지</td>
<td><input type="file" name="img" accept="image/png,image/jpg"></td>
</tr>
2. form 부분 속성 추가
<form method = "post" action = "/user/join_success" enctype ="multipart/form-data">
http 통신이라는 것은 header 부분도 있고..body도 잇고..
req.body 쓰는 이유 - 정보가 실질적으로 body에 들어가 있어서
이미지가 내용에 들어갈 수 있도록
파일을 받으려면 form 이 준비가되어 있어야함.
body 라는 영역이 post 값만 넘길 때는 공간이 적다.
body영역을 키워 놓자 ! 라는 뜻으로 이해하기
저걸 써야 html에서 server에 값을 보낼 때 image 값도 보낼 수 있다 !
최종 views- join.html
join.html <br/>
회원가입 PAGE <br/>
<form method = "post" action = "/user/join_success" enctype ="multipart/form-data">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" name ="userid" >
</td>
</tr>
<tr>
<td>비번</td>
<td>
<input type ="text" name ="userpw" >
</td>
</tr>
<tr>
<td>이름</td>
<td>
<input type ="text" name ="username" >
</td>
</tr>
<tr>
<td>성별</td>
<td>
<input type ="radio" name ="gender" value="0" checked >남자
<input type ="radio" name ="gender" value="1" >여자
</td>
</tr>
<tr>
<td>이미지</td>
<td><input type="file" name="img"></td>
</tr>
</table>
<input type="submit" value="회원가입하기">
</form>
받는 부분도 준비하기 ★
post값 받는 부분 (body-parser 다운했었음)
이미지도 multipart 부분을 사용하려면 express에 다운받아야함.
3. npm install multer 명령 실행
이 녀석의 사용법 조금 새로운 개념이 들어감 ..
* multer 의 사용법
app.user('/', ____middle ware ____, router)
middle ware 두가지가 들어갈 수 잇다.
test
app.get에 두 개의 callback 함수가 들어가 있음
-> hello world 만 찍힘
but 에러는 안나온다.
next 인자값을 추가하고
next(); 를 추가하면? -> 둘 ㄷ ㅏ 실행 ok
next(); 실행하고 다음 꺼 실행
보기 쉽게 함수를 변수에 담아서 check!
get으로 했지만 router.get 도 다 똑같다 ~
middle ware
콜백함수 3개 이상도 되는지 ?? 질문쓰 ok
된대 ~
next()만 있다면.. 끝없이.....
즉, 하나의 url 값에 두 가지의 callback 함수가 들어갈 수 있다.
만약 위와같이 뭔가 많은 ~~ 게 있으면 당황하지말고 요건 콜백함수를 많이 넣었구나 ~ next()가 있겠구나 ~ 라고 이해하기.
4. 이미지 업로드
방법은 2가지가 있다.
multer라는 midlle ware가 들어간다. (위 설명과 연관 있음 )
방법 1 . routers - user - index.js
- multer 가져오기
- multer 세팅 값 - 외워 ~
- multer() method의 안에 객체 인자값 1개가 들어간다.
- storage, filename 두개의 속성이 들어감
1. routers - user - index.js 추가
const multer = require('multer');
const upload = multer({
storage:multer.diskStorage({
destination:function(req,file,callback){
callback(null,'uploads/') // 폴더명 : uploads
},
filename:function(req,file,callback){
callback(null, new Date().valueOf())
}
}),
})
외워서 그냥 쓰라게 편하다고 하심. 그래도 내용 의미 찾아보기 !
아래도 추가
router.post('/join_success', upload.single('img'), userController.join_success);
single() 안에 값은 image input name 이 img ! 요 값을 넣어주기
2. npm install path
routers - user - index.js 추가
const path = require('path')
그리고 변수 upload에 확장자 가져오는 코드 추가
const upload = multer({
storage:multer.diskStorage({
destination:function(req,file,callback){
callback(null,'uploads/') // 폴더명 : uploads
},
filename:function(req,file,callback){
callback(null, new Date().valueOf() + path.extname(file.originalname))
}
}),
})
추가한 코드 : 확장자 가져오는 코드
3. uploads 폴더 만들기
4. server 키고 회원가입 이미지 올려서 확인해보기
회원가입하면
uploads 폴더 안에 해당 사진이 들어감. !
이미지 업로드 흐름 이해하기
Client ---------req-------> Server
Client <---------res------- Server 응답 : 성공 실패든 모두 줌.
Client -> = form
파일
- 엑셀
- 이미지
컴퓨터 언어 -> 0, 1, ( +C )
이미지의 경우 엄청 글자가 많 ~ 이 적힌 파일의 영역임
)
ex)
-> 한 파일의 text양
multipart form 보낸 이유 (text양이 겁 ~ 나 많다. )
텍스트만 가지고 server가 파일을 만드는 것..
server의 역할 -> text라는 파일을 가지고 처음에 임시폴더에 text로 저장
우리가 multer package를 사용하게되면 -> 내용을 가공해서 우리가 원하는 위치에 파일을 생성, 옮겨 확장자를 붙여 주는 것.
즉, 이미지도 엄~ 청 긴 text일 뿐이다.
신기하군,,,,,,,,,,,,,,,,,,,,
그래서 다시 위에 작성한 코드를 보면
-> 어디에 저장할건지
-----------------------------------------
-> 어떤 이름으로 저장할건지
-> img에 담은 엄청나게 긴 text (image)를 따로 빼서 처리한 것 ( 너무 커서 )
---------------------------------------------Client -> Server 옮겨주는 것까지 함 ---------------------------------------------
지금 server만 이미지를 가지고 있으니 DB에도 연결해주기
그럼 server가 DB에게 이미지를 줘야하나요??
DB에는 이미지 자체를 저장하지않음.
왜냐하면 DB에는 이미지를 그대로 저장하려면 옴청나게 큰 text를 저장해야하니깬..
실제 서버를 운영하게 된다면 '파일 server'라는 곳을 만들어서 파일 전용 저장공간을 만들거야
그런데 우리는 SERVER 한 개이니깐 그냥 쓰기
-> DB에는 파일 경로만 저장하기 ㅇㅇ... .
이제 할 작업 : DB에 파일 경로만 넣어주면 끗 ~
(실무에서도 파일 경로 지정은 같은데 따로 만든 파일 server에 파일을 모을 뿐 (?))
왜 join_success에 ?
join 은 data처리는 아니엇음 , data를 받아 넘길 준비하는 join ! -> submit을 하면 join_success.html 로 갔음
router.post('/join_success', upload.single('img'), userController.join_success);
그래서 join_success 에서 파일을 받고 처리한 것
이제 DB 저장하는 것 배우기
1. 파일 경로 가져오기
routers- user - user.controller.js 추가
let userimage = req.file.path; // req.file : object
req.file : object
path 정보 ( 즉, 경로!)
req.file 안에 있는 path 가져오기
왜 다른 변수들과 다르게 바로 req.file.path 인지?
router.post('/join_success', upload.single('img'), userController.join_success);
여기서 처리했기 때문에 바로 사용이 가능하다.
2. userimage 추가
User.create({
userid,userpw,username, gender, userimage
})
res.render('./user/join_success.html',{
userid, userpw, username, gender, userimage
});
server on~
3. 새로 회원가입을 해보면 DB에 잘 들어감.
질문
??
join_success.html 에
join_success.html <br/>
{{userimage}} <br/>
{{username}}님 환영합니다. <br/>
{{username}}님의 ID 는 {{userid}}입니다.
{{userimage}} 를 넣었지만 아래처럼 나온다.
경로가 나옴...
이미지로 어떻게 나오게 한눈거지
app.use(express.static('uploads'));
app.use('/uploads',express.static(__dirname+'/uploads'));
경로에 uploads 는 안나와 (여기서 'uploads' 파일 쓴다고 선언해서) 만약 쓰고 싶으면 위에 처럼 '/uploads' 가상의 이름 적기
user.controller.js 에서
let userimage = req.file == undefined ? '' : req.file.filename; // 역슬래시를 뺀거
let userimage = req.file == undefined ? '' : req.file.path; -> path 는 경로까지 나와서 역슬래시가 나옴
이미지를 안넣었을 때 처리방법
예외처리 해주기
1. routers - user - user.controller.js
삼항 조건 연산자 ' '
// let userimage = req.file.path; // req.file : object
let userimage = req.file == undefined ? '' : req.file.path;
server on
2. 이미지 없이 회원가입 -> userimage 값이 ' ' 아무것도 없다.
3. 이미지 넣고 회원가입 -> userimage 값 = 경로로 잘 들어온다.
-----------------------------------------------------------------------------------------------------------------------------------
AJAX 사용하여 RELOADING 없이 PAGE 구현 하기
-----------------------------------------------------------------------------------------------------------------------------------
회원가입 쪽 보기
보통 password 두번씩 누르게 하고 두 개가 다르면 다르다고 말하는 기능도 !
지금까지는
이번에는 잘 가공해서 넣기.
이제 해볼 것
아이디 중복체크
패스워드 확인 (두 번 입력 / 일치 여부)
이름 글자 길이 check
쉬운 것 부터 ㄱ ㄱ !
1. 이름 글자 길이 check
views - user - join.html
<tr>
<td>이름</td>
<td>
<input type ="text" name ="username" maxlength="20">
</td>
</tr>
이름, id 는 길 수도 있으니 ...
maxlength="20" 를 반드시 쓰는 곳은 주민등록번호 or 전화번호 등 자릿수가 정해진 것!
2. 패스워드 확인 (두 번 입력 / 일치 여부)
<tr>
<td>패스워드</td>
<td>
<input type ="text" name ="userpw" >
</td>
</tr>
<tr>
<td>패스워드 확인</td> // 추가
<td>
<input type ="text" name ="userpw_check" >
</td>
</tr>
id 값 추가
<tr>
<td>패스워드</td>
<td>
<input type ="text" name ="userpw" id ="userpw">
</td>
</tr>
<tr>
<td>패스워드 확인</td>
<td>
<input type ="text" name ="userpw_check" id="userpw_check" >
</td>
</tr>
function 추가
join.html <br/>
회원가입 PAGE <br/>
<form method = "post" action = "/user/join_success" enctype ="multipart/form-data">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" name ="userid" >
</td>
</tr>
<tr>
<td>패스워드</td>
<td>
<input type ="text" name ="userpw" id ="userpw">
</td>
</tr>
<tr>
<td>패스워드 확인</td>
<td>
<input type ="text" name ="userpw_check" id="userpw_check" >
</td>
</tr>
<tr>
<td>이름</td>
<td>
<input type ="text" name ="username" maxlength="20">
</td>
</tr>
<tr>
<td>성별</td>
<td>
<input type ="radio" name ="gender" value="0" checked >남자
<input type ="radio" name ="gender" value="1" >여자
</td>
</tr>
<tr>
<td>이미지</td>
<td><input type="file" name="img"></td>
</tr>
</table>
<input type="submit" value="회원가입하기">
</form>
<script type ="text/javascript">
function password_check (){
let pwd1 = document.querySelector('#userpw');
let pwd2 = document.querySelector('#userpw_check');
console.log(pwd1.value, pwd2.value);
}
</script>
sumit 에 id 값 추가
<input type="submit" id = "login_submit" value="회원가입하기">
btn 변수에 event 추가
<script type ="text/javascript">
function password_check(){
let pwd1 = document.querySelector('#userpw');
let pwd2 = document.querySelector('#userpw_check');
console.log(pwd1value, pwd2.value);
}
const btn = document.querySelector('#login_submit');
btn.addEventListener('click', ()=>{
console.log('aa')
return false;
})
</script>
button으로 바꾸기
<input type="button" id = "login_submit" value="회원가입하기">
서버 on
form id 값 입력
<form method = "post" id = "login_form" action = "/user/join_success" enctype ="multipart/form-data">
script에 아래 입력
const login_form = document.querySelector('#login_form')
btn.addEventListener('click', ()=>{
console.log('aa')
login_form.submit();
})
전체
join.html <br/>
회원가입 PAGE <br/>
<form method = "post" id = "login_form" action = "/user/join_success" enctype ="multipart/form-data">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" name ="userid" >
</td>
</tr>
<tr>
<td>패스워드</td>
<td>
<input type ="text" name ="userpw" id ="userpw">
</td>
</tr>
<tr>
<td>패스워드 확인</td>
<td>
<input type ="text" name ="userpw_check" id="userpw_check" >
</td>
</tr>
<tr>
<td>이름</td>
<td>
<input type ="text" name ="username" maxlength="20">
</td>
</tr>
<tr>
<td>성별</td>
<td>
<input type ="radio" name ="gender" value="0" checked >남자
<input type ="radio" name ="gender" value="1" >여자
</td>
</tr>
<tr>
<td>이미지</td>
<td><input type="file" name="img"></td>
</tr>
</table>
<input type="button" id = "login_submit" value="회원가입하기">
</form>
<script type ="text/javascript">
function password_check(){
let pwd1 = document.querySelector('#userpw');
let pwd2 = document.querySelector('#userpw_check');
console.log(pwd1value, pwd2.value);
}
const btn = document.querySelector('#login_submit');
const login_form = document.querySelector('#login_form')
btn.addEventListener('click', ()=>{
console.log('aa')
login_form.submit();
})
</script>
server on - 실행 해보기
JS로도 submit을 보낼 수 있다.
이제 조건이 맞는 경우에만 실행 시키기
-> 코드 추가 및 수정
join.html <br/>
회원가입 PAGE <br/>
<form method = "post" id = "login_form" action = "/user/join_success" enctype ="multipart/form-data">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" name ="userid" >
</td>
</tr>
<tr>
<td>패스워드</td>
<td>
<input type ="text" name ="userpw" id ="userpw">
</td>
</tr>
<tr>
<td>패스워드 확인</td>
<td>
<input type ="text" name ="userpw_check" id="userpw_check" >
</td>
</tr>
<tr>
<td>이름</td>
<td>
<input type ="text" name ="username" maxlength="20">
</td>
</tr>
<tr>
<td>성별</td>
<td>
<input type ="radio" name ="gender" value="0" checked >남자
<input type ="radio" name ="gender" value="1" >여자
</td>
</tr>
<tr>
<td>이미지</td>
<td><input type="file" name="img"></td>
</tr>
</table>
<input type="button" id = "login_submit" value="회원가입하기">
</form>
<script type ="text/javascript">
function paassword_check(){
let pwd1 = document.querySelector('#userpw');
let pwd2 = document.querySelector('#userpw_check');
console.log(pwd1value, pwd2.value);
return pwd1.value == pwd2.value;
}
const btn = document.querySelector('#login_submit');
const login_form = document.querySelector('#login_form')
btn.addEventListener('click', ()=>{
pwd_check = password_check();
// Pwd가 맞을 경우 true, 틀리면 false
if(pwd_check){
login_form.submit();
}else{
alert('패스워드가 일치하지 않습니다.')
}
})
</script>
pwd 불일치로 다시 돌아왔을 때 안의 내용 지우기
btn.addEventListener('click', ()=>{
pwd_check = password_check();
// Pwd가 맞을 경우 true, 틀리면 false
if(pwd_check){
login_form.submit();
}else{
pwd1.value = '';
pwd2.value = '';
pwd1.focus(); // 마우스 커서 이동
alert('패스워드가 일치하지 않습니다.')
}
})
틀려서 다시 오게 되면 마우스 커서 pwd1에 위치하도록 만들기
전체
join.html <br/>
회원가입 PAGE <br/>
<form method = "post" id = "login_form" action = "/user/join_success" enctype ="multipart/form-data">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" name ="userid" >
</td>
</tr>
<tr>
<td>패스워드</td>
<td>
<input type ="text" name ="userpw" id ="userpw">
</td>
</tr>
<tr>
<td>패스워드 확인</td>
<td>
<input type ="text" name ="userpw_check" id="userpw_check" >
</td>
</tr>
<tr>
<td>이름</td>
<td>
<input type ="text" name ="username" maxlength="20">
</td>
</tr>
<tr>
<td>성별</td>
<td>
<input type ="radio" name ="gender" value="0" checked >남자
<input type ="radio" name ="gender" value="1" >여자
</td>
</tr>
<tr>
<td>이미지</td>
<td><input type="file" name="img"></td>
</tr>
</table>
<input type="button" id = "login_submit" value="회원가입하기">
</form>
<script type ="text/javascript">
const pwd1 = document.querySelector('#userpw');
const pwd2 = document.querySelector('#userpw_check');
const btn = document.querySelector('#login_submit');
const login_form = document.querySelector('#login_form')
function password_check(){
console.log(pwd1.value, pwd2.value);
return pwd1.value == pwd2.value;
}
btn.addEventListener('click', ()=>{
pwd_check = password_check();
// Pwd가 맞을 경우 true, 틀리면 false
if(pwd_check){
login_form.submit();
}else{
pwd1.value = '';
pwd2.value = '';
pwd1.focus(); // 마우스 커서 이동
alert('패스워드가 일치하지 않습니다.')
}
})
</script>
지금 한 것들 -> 웹 퍼블리셔 개발자 + 백 엔드쪽도 = 많은 것을 하고 잇다,,, 인지 해.. 넹..
아이디 중복체크
1. p tag 영역 하나 만들기
<tr>
<td>아이디</td>
<td>
<input type ="text" name ="userid" >
<p id ="userid_msg"></p>
</td>
</tr>
2. script 에도 추가
<script type ="text/javascript">
const pwd1 = document.querySelector('#userpw');
const pwd2 = document.querySelector('#userpw_check');
const btn = document.querySelector('#login_submit');
const login_form = document.querySelector('#login_form')
const userid_msg = document.querySelector('#userid_msg'); // 추가
3. script 에 function (){} 추가
function userid_check(){
//ajax를 통해 data를 가져왔다고 가정하자!
// 중복이면 false, 중복아니면 true 값 !@
login_flag = true; // 중복되지 않았다를 기본 값 / ajax에서 받을거
if (login_flag){
userid_msg.innerHTML='올바른 아이디입니다.'
userid_msg.style.color='green';
}else{
userid_msg.innerHTML='이미 해당 아이디가 있습니다.'
userid_msg.style.color='red';
}
}
이 함수는 언제 ?
-> 마우스 커서가 input text에서 사라졌을 때.
* 패스워드 type ="password"로 고치기
4. 아이디 text에 id 값 추가
<tr>
<td>아이디</td>
<td>
<input type ="text" id = "userid" name ="userid" >
<p id ="userid_msg">올바른 아이디입니다.</p>
</td>
</tr>
const userid = document.querySelector('#userid');
userid.addEventListener('focusout',userid_check)
join.html 전체
join.html <br/>
회원가입 PAGE <br/>
<form method = "post" id = "login_form" action = "/user/join_success" enctype ="multipart/form-data">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" id = "userid" name ="userid" >
<p id ="userid_msg"></p>
</td>
</tr>
<tr>
<td>패스워드</td>
<td>
<input type ="text" name ="userpw" id ="userpw">
</td>
</tr>
<tr>
<td>패스워드 확인</td>
<td>
<input type ="text" name ="userpw_check" id="userpw_check" >
</td>
</tr>
<tr>
<td>이름</td>
<td>
<input type ="text" name ="username" maxlength="20">
</td>
</tr>
<tr>
<td>성별</td>
<td>
<input type ="radio" name ="gender" value="0" checked >남자
<input type ="radio" name ="gender" value="1" >여자
</td>
</tr>
<tr>
<td>이미지</td>
<td><input type="file" name="img"></td>
</tr>
</table>
<input type="button" id = "login_submit" value="회원가입하기">
</form>
<script type ="text/javascript">
const pwd1 = document.querySelector('#userpw');
const pwd2 = document.querySelector('#userpw_check');
const btn = document.querySelector('#login_submit');
const login_form = document.querySelector('#login_form')
const userid_msg = document.querySelector('#userid_msg');
const userid = document.querySelector('#userid');
function password_check(){
console.log(pwd1.value, pwd2.value);
return pwd1.value == pwd2.value;
}
function userid_check(){
//ajax를 통해 data를 가져왔다고 가정하자!
// 중복이면 false, 중복아니면 true 값 !@
login_flag = true; // 중복되지 않았다를 기본 값 / ajax에서 받을거
if (login_flag){
userid_msg.innerHTML='올바른 아이디입니다.'
userid_msg.style.color='green';
}else{
userid_msg.innerHTML='이미 해당 아이디가 있습니다.'
userid_msg.style.color='red';
}
}
userid.addEventListener('focusout',userid_check)
btn.addEventListener('click', ()=>{
pwd_check = password_check();
// Pwd가 맞을 경우 true, 틀리면 false
if(pwd_check){
login_form.submit();
}else{
pwd1.value = '';
pwd2.value = '';
pwd1.focus(); // 마우스 커서 이동
alert('패스워드가 일치하지 않습니다.')
}
})
</script>
server on and check
ajax 통해서 요청하기
1. ajax 사용위한 axios 추가
요건 라이브러리
npm install 과 비슷하다.
누가 만든 것을 우리가 가져다 쓰는 것
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
2. 함수 내용 추가
async function userid_check(){
let data = await axios.get('http://localhost:3000/user/userid_check') //요청 보내기
//ajax를 통해 data를 가져왔다고 가정하자!
// 중복이면 false, 중복아니면 true 값 !@
login_flag = true; // 중복되지 않았다를 기본 값 / ajax에서 받을거
if (login_flag){
userid_msg.innerHTML='올바른 아이디입니다.'
userid_msg.style.color='green';
}else{
userid_msg.innerHTML='이미 해당 아이디가 있습니다.'
userid_msg.style.color='red';
}
}
axios.get 을 사용하면 반환 값 = Promise 객체로 주니까 async , await 씀
저 url에 요청을 보낼거야
아직 url 만든 적이 없으니 이제 만들자
3. 함수 에 userid.value query sting
async function userid_check(){
let data = await axios.get(`http://localhost:3000/user/userid_check?userid=${userid.value}`)
우기ㅏ 적은 userid 값을 ---> server 가 받아서 ---> DB ----> check ---> json형태로 떨궈주는 값을 가지고 중복이냐 아니냐를 판별해서 login_flag 안에다가 넣어주면 완 성 ^^..
server쪽 userid_check 만들러 가기 !
user라는 대분류 있고
userid_check 소분류 만들기
4. routers - user - index.js
const express = require('express');
const router = express.Router();
const userController = require('./user.controller')
const multer = require('multer');
const path = require('path');
const upload = multer({
storage:multer.diskStorage({
destination:function(req,file,callback){
callback(null,'uploads/') // 폴더명 : uploads
},
filename:function(req,file,callback){
callback(null, new Date().valueOf() + path.extname(file.originalname))
}
}),
})
router.get('/join',userController.join);
router.post('/join_success', upload.single('img'), userController.join_success);
router.get('/login', userController.login);
router.post('/login_check', userController.login_check);
router.get('/logout', userController.logout);
router.get('/info', userController.info);
router.get('/userid_check', userController.userid_check); //추가
module.exports=router;
5. routers - user - user.controller.js 추가
let userid_check = (req,res)=>{
res.json({
login:true,
})
}
module.exports ={
join, join_success, login, login_check, logout, info, userid_check,
}
server on
브라우저에 localhost:3000/user/userid_check 입력
json으로 보낸 객체가 나옴
----------------------------------------------요 url 값으로 요청하면 -> true 를 주는 -----------------------------------------
6. user.controller.js 수정
let userid_check = (req,res)=>{
let userid = req.query.userid;
res.json({
login:true,
userid,
})
}
server on
url = http://localhost:3000/user/userid_check?userid=양말주세요 입력해보기
userid = "" 값이 달라질때마다 json 값도 바뀌는 거 확인
7. get값으로 받은 userid 값을 db에 접속해서 있는지 없는지 확인
user.controller.js
let userid_check = async (req,res)=>{
let userid = req.query.userid;
let flag = false; //default값 false
let result = await User.findOne({ //비동기 처리 //query문 결과 받을 때까지 기다렸다가 result 변수에 넣음
where:{userid}
})
//result - undefined = 값이 없으니 userid 생성 가능 /
//result 값이 있으면 생성 불가능
if(result==undefined){
flag = true;
}else{ // deflaut 값이 false라서 사실 else쪽은 필요없음.
flag = false;
}
res.json({
login:flag, //flag BOOLEAN값을 넣어 주기
userid,
})
}
server on
다시 브라우저에
http://localhost:3000/user/userid_check?userid=양말주세요 //false,
http://localhost:3000/user/userid_check?userid=양말줘 //true
userid 값이 존재하면 - false, 존재하지 않으면 - true
8. views- join.html에 console.log(data) 해보기
async function userid_check(){
let data = await axios.get(`http://localhost:3000/user/userid_check?userid=${userid.value}`) //요청 보내기
console.log(data);
data 안에 내용 잘 뜨는지 확인
data 안에 login -> true , false값 반환 가능
async function userid_check(){
let data = await axios.get(`http://localhost:3000/user/userid_check?userid=${userid.value}`) //요청 보내기
console.log(data);
//ajax를 통해 data를 가져왔다고 가정하자!
// 중복이면 false, 중복아니면 true 값 !@
login_flag = data.data.login; // 중복되지 않았다를 기본 값 / ajax에서 받을거
if (login_flag){
userid_msg.innerHTML='올바른 아이디입니다.'
userid_msg.style.color='green';
}else{
userid_msg.innerHTML='이미 해당 아이디가 있습니다.'
userid_msg.style.color='red';
}
}
data.data.login; 추가
server on
localhost:3000/user/join 입력 -> 내용 쳌
이런식으로 ajax 의 이용해서 page 의 reloading 없이 중복체크 가능 !
요 부분은 join_success
ㅁ ㅓ
ㅇ
===================================파일 ======================================
server.js
const express = require('express');
const app = express();
const {sequelize}=require('./models')
const nunjucks = require('nunjucks');
const bodyParser = require('body-parser')
const routers = require('./routers')
const session = require('express-session')
const cors = require('cors');
app.use(express.static('uploads'));
app.use(session({
secret:'aaa',
resave:false,
saveUninitialized:true,
}))
app.use(bodyParser.urlencoded({extended:false}));
nunjucks.configure('views',{
express:app,
})
app.set('view engine', 'html')
app.use(cors())
sequelize.sync({force:false})
.then(()=>{
console.log('접속 성공')
}).catch(()=>{
console.log('접속 실패')
})
app.use('/',routers);
app.listen(3000,()=>{
console.log('server start port : 3000')
})
models - user.js
const Sequelize = require('sequelize') // Class
const moment = require('moment');
module.exports = class User extends Sequelize.Model{
static init(sequelize){
return super.init({
userid:{
type:Sequelize.STRING(20),
allowNull:false,
unique:true,
},
userpw:{
type:Sequelize.STRING(20),
allowNull:false,
},
username:{
type:Sequelize.STRING(20),
allowNull:false,
},
gender:{
type:Sequelize.BOOLEAN,
allowNull:false,
},
userimage:{
type:Sequelize.STRING(100),
allowNull:true,
},
userdt:{
type:Sequelize.DATEONLY,
allowNull:false,
defaultValue:Sequelize.NOW,
get: function(){
return moment(this.getDataValue('userdt')).format('YYYY-MM-DD') //field명
}
}
},{
sequelize,
timestamps:false,
underscored:false,
paranoid:false,
modelName:"User",
tableName:"users0510",
charset:"utf8",
collate:"utf8_general_ci",
})
}
static associate (db){}
}
models - index.js
'use strict';
// const path = require('path');
const Sequelize = require('sequelize');
// const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
const User = require('./user');
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
db.User = User;
User.init(sequelize);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
routers - index.js
const express=require('express');
const router = express.Router();
const main = require('./main')
const user = require('./user')
router.use('/user', user);
router.use('/',main);
module.exports = router;
routers - main - index.js
const express = require('express');
const router = express.Router();
const mainController = require('./main.controller')
router.use('/', mainController.main);
module.exports=router;
routers - main - main.controller.js
let main = (req,res)=>{
console.log(req.session);
res.render('index.html',{
userid:req.session.uid,
isLogin:req.session.isLogin
});
}
module.exports.main = main; // (뒤에가 함수)
routers - user - index.js
const express = require('express');
const router = express.Router();
const userController = require('./user.controller')
const multer = require('multer');
const path = require('path');
const upload = multer({
storage:multer.diskStorage({
destination:function(req,file,callback){
callback(null,'uploads/') // 폴더명 : uploads
},
filename:function(req,file,callback){
callback(null, new Date().valueOf() + path.extname(file.originalname))
}
}),
})
router.get('/join',userController.join);
router.post('/join_success', upload.single('img'), userController.join_success);
router.get('/login', userController.login);
router.post('/login_check', userController.login_check);
router.get('/logout', userController.logout);
router.get('/info', userController.info);
router.get('/userid_check', userController.userid_check);
module.exports=router;
routers - user - user.controller.js
const {User} = require('../../models');
// const { findAll } = require('../../models/user');
let join = (req,res)=>{
res.render('./user/join.html');
}
let join_success = async (req,res)=>{
let userid = req.body.userid;
let userpw = req.body.userpw;
let username = req.body.username;
let gender = req.body.gender;
// let userimage = req.file.path; // req.file : object
let userimage = req.file == undefined ? '' : req.file.filename;
await User.create({
userid,userpw,username, gender, userimage
})
res.render('./user/join_success.html',{
userid, userpw, username, gender, userimage
});
}
let login = (req,res)=>{
let flag = req.query.flag;
res.render('./user/login.html',{flag});
}
let login_check = async (req,res)=>{
let userid = req.body.userid;
let userpw = req.body.userpw;
let result = await User.findOne({
where:{userid, userpw}
})
console.log(result);
if(result == null){
res.redirect('/user/login?flag=0')
}else{
req.session.uid = userid;
req.session.isLogin = true;
req.session.save(()=>{
res.redirect('/');
})
}
}
let logout = (req,res)=>{
delete req.session.isLogin;
delete req.session.uid;
req.session.save(()=>{
res.redirect('/');
})
}
let info = async (req,res)=>{
let result = await User.findAll({});
res.render('./user/info.html', {
result,
})
// res.json({
// result,
// })
}
let userid_check = async (req,res)=>{
let userid = req.query.userid;
let flag = false; //default값 false
let result = await User.findOne({ //비동기 처리 //query문 결과 받을 때까지 기다렸다가 result 변수에 넣음
where:{userid}
})
//result - undefined = 값이 없으니 userid 생성 가능 /
//result 값이 있으면 생성 불가능
if(result==undefined){
flag = true;
}else{ // deflaut 값이 false라서 사실 else쪽은 필요없음.
flag = false;
}
res.json({
login:flag, //flag BOOLEAN값을 넣어 주기
userid,
})
}
module.exports ={
join, join_success, login, login_check, logout, info, userid_check,
}
views - user - info.html
<table>
<tr>
<td>번호</td>
<td>아이디</td>
<td>비번</td>
<td>이름</td>
<td>성별</td>
<td>사진</td>
<td>등록일</td>
</tr>
{% for item in result %}
<tr>
<td>{{item.dataValues.id}}</td>
<td>{{item.dataValues.userid}}</td>
<td>{{item.dataValues.userpw}}</td>
<td>{{item.dataValues.username}}</td>
<td>{{item.dataValues.gender}}</td>
<td>{{item.dataValues.userimage}}</td>
<td>{{item.dataValues.userdt}}</td>
</tr>
{% endfor %}
</table>
views - user - join_success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
join_success.html <br/>
<div> <img src= "http://localhost:3000/{{userimage}}"></div> <br/>
{{username}}님 환영합니다. <br/>
{{username}}님의 ID 는 {{userid}}입니다.
<script type ="text/javascript">
</script>
</body>
</html>
views - user - join.html
join.html <br/>
회원가입 PAGE <br/>
<form method = "post" id = "login_form" action = "/user/join_success" enctype ="multipart/form-data">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" id = "userid" name ="userid" >
<p id ="userid_msg"></p>
</td>
</tr>
<tr>
<td>패스워드</td>
<td>
<input type ="password" name ="userpw" id ="userpw">
</td>
</tr>
<tr>
<td>패스워드 확인</td>
<td>
<input type ="password" name ="userpw_check" id="userpw_check" >
</td>
</tr>
<tr>
<td>이름</td>
<td>
<input type ="text" name ="username" maxlength="20">
</td>
</tr>
<tr>
<td>성별</td>
<td>
<input type ="radio" name ="gender" value="0" checked >남자
<input type ="radio" name ="gender" value="1" >여자
</td>
</tr>
<tr>
<td>이미지</td>
<td><input type="file" name="img"></td>
</tr>
</table>
<input type="button" id = "login_submit" value="회원가입하기">
</form>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script type ="text/javascript">
const pwd1 = document.querySelector('#userpw');
const pwd2 = document.querySelector('#userpw_check');
const btn = document.querySelector('#login_submit');
const login_form = document.querySelector('#login_form')
const userid_msg = document.querySelector('#userid_msg');
const userid = document.querySelector('#userid');
function password_check(){
console.log(pwd1.value, pwd2.value);
return pwd1.value == pwd2.value;
}
async function userid_check(){
let data = await axios.get(`http://localhost:3000/user/userid_check?userid=${userid.value}`) //요청 보내기
console.log(data);
//ajax를 통해 data를 가져왔다고 가정하자!
// 중복이면 false, 중복아니면 true 값 !@
login_flag = data.data.login; // 중복되지 않았다를 기본 값 / ajax에서 받을거
if(userid.value==''){
userid_msg.innerHTML='아이디를 입력해주세요'
}else if (login_flag){
userid_msg.innerHTML='올바른 아이디입니다.'
userid_msg.style.color='green';
}else{
userid_msg.innerHTML='이미 해당 아이디가 있습니다.'
userid_msg.style.color='red';
}
}
userid.addEventListener('focusout',userid_check)
btn.addEventListener('click', ()=>{
pwd_check = password_check();
// Pwd가 맞을 경우 true, 틀리면 false
if(pwd_check){
login_form.submit();
}else{
pwd1.value = '';
pwd2.value = '';
pwd1.focus(); // 마우스 커서 이동
alert('패스워드가 일치하지 않습니다.')
}
})
</script>
views-user - login.html
login.html <br/>
<form method = "post" action ="/user/login_check">
<table>
<tr>
<td>아이디</td>
<td>
<input type ="text" id ="userid" name = "userid">
</td>
</tr>
<tr>
<td>비밀번호 </td>
<td>
<input type ="text" id ="userpw" name = "userpw">
</td>
</tr>
</table>
<input type ="submit" value = "로그인하기">
</form>
{% if flag == '0' %}
<script type = "text/javascript">
alert('아이디와 패스워드를 확인해주세요');
const id = document.querySelector('#userid');
const pw = document.querySelector('#userpw');
id.setAttribute('style', 'background:lightsalmon');
pw.setAttribute('style', 'background:lightsalmon');
id.addEventListener('focus', ()=>{
id.setAttribute('style', 'background:#fff');
})
pw.addEventListener('focus', ()=>{
pw.setAttribute('style', 'background:#fff');
})
</script>
{% endif %}
views - index.html
{% if isLogin %}
{{userid}}님 환영합니다. <br/>
<a href = "/user/logout" > 로그아웃 </a>
<a href = "/user/info">회원 정보</a>
{% else %}
<a href="/user/login" >로그인</a>
<a href="/user/join" >회원가입</a>
{% endif %}
질문 : npm 잘못 다운 중 일 떄 어떤걸로 멈추셨는지?
그냥 Ctrl + c 누르면 작업 멈출까? 가 뜸. 오호..