soket과 http의 차이
soket은 emit을 통해 한번 열어주면 닫지 않을때까지 계속 열려 있다. 그렇기 때문에 실시간 채팅이 가능하다
http는 한번 통신 한 후에 닫기 때문에 실시간으로 채팅을 하기에는 어려움이 있다.
씨퀄라이즈와 포스트맨을 통해 만든 테이블에 값 넣고 가져오기
메인 폴더(230810_JOIN)의 index.js
const express = require ( 'express' );
const app = express ();
const PORT = 8080 ;
const db = require ( './models' );
app . set ( 'view engine' , 'ejs' );
app . use ( '/views' , express . static ( './views' ));
app . use ( '/static' , express . static ( './static' ));
app . use ( express . json ());
app . use ( express . urlencoded ({ extended : true }));
const router = require ( './routes/student' );
app . use ( '/' , router );
db . sequelize . sync ({ force : true }). then (() => { //true 값을 넣어야 다시 index.js를 실행할 때 삭제하고 다시만들어준다.
app . listen ( PORT , () => {
console . log ( `http://localhost: ${ PORT } ` );
});
});
어제와 동일하다
routes 역할의 student.js
const express = require ( 'express' );
const router = express . Router ();
const controller = require ( '../controller/Cstudent' );
router . get ( '/' , controller . index );
router . post ( '/student' , controller . post_student );
router . post ( '/class' , controller . post_class );
router . get ( '/student' , controller . get_student );
module . exports = router ;
controller의 Cstudent.js
const { Student , StudentProfile , Classes } = require ( '../models' )
// 구조 분해 할당으로 값을 넣어줘서 model.~로 안하게함 사실 import를 쓰면 됨
exports . index = ( req , res ) => {
res . render ( 'index' );
}
//학생 생성
exports . post_student = async ( req , res ) => {
try {
const { userid , password , email , name , major , enroll } = req . body ;
const user = await Student . create ({
userid ,
password ,
email ,
StudentProfile : {
name ,
major ,
enroll ,
},
}, { include : StudentProfile }
);
console . log ( user );
res . send ( user );
} catch ( error ) {
console . log ( error );
}
}
exports . post_class = async ( req , res ) => {
try {
const { name , room , code , teacher_name , StudentId } = req . body
const classes = await Classes . create ({
name ,
room ,
code ,
teacher_name ,
StudentId ,
})
} catch ( error ){
}
}
exports . get_student = async ( req , res ) => {
try {
const student = await Student . findAll ({
attributes : [ 'userid' , 'email' ],
include : [{ model : StudentProfile , attributes : [ 'major' , 'enroll' ]}]
});
res . send ( student );
} catch ( error ) {
console . log ( err );
}
}
model 폴더의 Classes.js
const { DataTypes } = require ( "sequelize" );
const { sequelize } = require ( "." );
const classModel =( sequelize ) => {
const Classes = sequelize . define (
'Classes' ,
{
id : {
type : DataTypes . INTEGER ,
allowNull : false ,
primaryKey : true ,
autoIncrement : true ,
},
name : {
type : DataTypes . STRING ( 31 ),
allowNull : false ,
},
room : {
type : DataTypes . STRING ( 7 ),
},
code : {
type : DataTypes . STRING ( 7 ),
allowNull : false ,
},
teacher_name : {
type : DataTypes . STRING ( 15 ),
},
});
return Classes ;
};
module . exports = classModel ;
model 폴더의 Student.js
const { DataTypes } = require ( "sequelize" )
const studentModel = ( sequelize ) => {
const Stdent = sequelize . define (
'Student' ,
{
id : {
type : DataTypes . INTEGER ,
allowNull : false ,
primaryKey : true ,
autoIncrement : true ,
},
userid : {
type : DataTypes . STRING ( 31 ),
allowNull : false ,
},
email : {
type : DataTypes . STRING ( 31 ),
},
password : {
type : DataTypes . STRING ( 255 ),
allowNull : false ,
}
});
return Stdent ;
}
module . exports = studentModel ;
model 폴더의 StudentProfile.js
const { DataTypes } = require ( "sequelize" )
const studentProfileModel = ( sequelize ) => {
const StudentProfile = sequelize . define ( 'StudentProfile' ,{
id : {
type : DataTypes . INTEGER ,
allowNull : false ,
primaryKey : true ,
autoIncrement : true ,
},
name : {
type : DataTypes . STRING ( 15 ),
allowNull : false ,
},
major : {
type : DataTypes . STRING ( 31 ),
allowNull : false ,
},
enroll : {
type : DataTypes . INTEGER ,
allowNull : false ,
}
});
return StudentProfile
};
module . exports = studentProfileModel ;
model 폴더의 index.js
'use strict' ;
const fs = require ( 'fs' );
const path = require ( 'path' );
const Sequelize = require ( 'sequelize' );
const process = require ( 'process' );
const basename = path . basename ( __filename );
const env = process . env . NODE_ENV || 'development' ;
const config = require ( __dirname + '/../config/config.json' )[ env ];
const db = {};
const sequelize = new Sequelize ( config . database , config . username , config . password , config );
//모델
db . Student = require ( './Students' )( sequelize );
db . Classes = require ( './Classes' )( sequelize );
db . StudentProfile = require ( './Studentprofile' )( sequelize );
//관계형성
//1:1 학생과 프로필
db . Student . hasOne ( db . StudentProfile );
db . StudentProfile . belongsTo ( db . Student );
//1:다 학생과 강의
db . Student . hasMany ( db . Classes ); //, {foreignKey: 'student_id'}외래키 지정을 안하면 알아서 지정을해준다.
db . Classes . belongsTo ( db . Student ); //, {foreignKey: 'student_id'}
db . sequelize = sequelize ;
db . Sequelize = Sequelize ;
module . exports = db ;
이렇게 하여서 node index.js를 실행시키면 지정한 데이터베이스에 테이블이 들어간다 그 후에 포스트맨에서 워크 스패이스를 만든 후 값들을 넣을 수 있다.
※ 여기서 model폴더의 index.js에서 외래키를 지정하던 문자을 빼서 씨퀄라이즈에서 자동으로 외래키를 만들어주는데 만들어줄때는 define으로 정의된 이름에 id를 CamelCase 형식으로 붙여서 외래키 이름을 만들어준다. 위의 코드를 실행한후 Classes와 StudentProfile에 생성된 외래키를 보면 다음과 같다
※ autoincrement는 id를 자동으로 갱신시켜준다.
포스트맨으로 값 넣고 가져오기
라우트에 있는 주소를 입력한 후 req.body로 받기 때문에 Body > raw > JSON으로 바꾸고 객체로 데이터를 보낼 수 있다. 이렇게 한 다음 send를 누르면 컨트롤러 폴더 Cstudent.js의 학생 생성 함수(?)가 돌아가고 값을 넣은 후에 다시 돌려보내준다.
classes 테이블에도 같은 방식으로 값을 넣는다.
그리고 원하는 데이터를 가져오기 위해 get을 이용한다
위와 같이 get으로 send를 해주면 라우터가 아래의 코드와 연결 시켜준 후에 원하는 이름을 입력하여 원하는 데이터를 받을 수 있다.
exports . get_student = async ( req , res ) => {
try {
const student = await Student . findAll ({
attributes : [ 'userid' , 'email' ],
include : [{ model : StudentProfile , attributes : [ 'major' , 'enroll' ]}]
});
res . send ( student );
} catch ( error ) {
console . log ( err );
}
}
Cookie와 Session
Cookie
웹브라우저에 저장되고 키와 값이 들어있는 작은 데이터 파일
[동작 방식]
1. 클라이언트가 페이지를 요청
2. 서버에서 쿠키를 생성
3.http 헤더에 쿠키를 포함하여 응답
4. 브라우저가 종료되어도 쿠키 만효 기간이 지나지 않았다면 클라이언트에서 보관하고 있다.
5. 같은 요청을 할 경우 http 헤더에 쿠키를 함께 보냄
6. 서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을때, 쿠키를 업데이트하고 http 헤더에 포함시켜 응답
위와 같은 방법으로 확인 가능
Cookie 사용하기
npm i cookie-parser 명령어로 설치한 후에
const cookieParser = require("cookie-parser");
app.use(cookieParser());
res.cookie('쿠키 이름', '쿠키값', '옵션 객체')
위의 방법으로 사용 가능하다.
npm init -y
npm i express ejs cookie-parser
import express from 'express' ;
import cookieParser from 'cookie-parser' ;
const app = express ();
const PORT = 8080 ;
app . set ( 'view engine' , 'ejs' );
app . use ( '/views' , express . static ( './views' ));
app . use ( '/static' , express . static ( './static' ));
app . use ( express . json ());
app . use ( express . urlencoded ({ extended : true }));
//쿠키 파서
// app.use(cookieParser());
//암호화
app . use ( cookieParser ( '12341234' ));
//쿠키 옵션
const cookieConfig = {
// httpOnly : 웹 서버를 통해서만 쿠키에 접근할 수 있다.
// 자바스크립트에서 document.cookie를 이용해서 쿠키에 접속하는 것을 차단한다.
// maxAge : 쿠키 수명 밀리초
// expires : 만료 날짜를 GMT시간 설정
// path: 해당 디렉토리와 하위 디렉토리에서만 경로가 활성화 되고 웹 브라우저는 해당하는 쿠키만 웹 서버에 전송된다
// 쿠키가 전송될 url을 특정할 수 있다 (기본값 : '/')
// domain : 쿠키가 전송될 도메인을 특정 가능 ( 기본 값 : 현재 도메인)
// secure : 웹 브라우저과 웹 서버가 https로 통신하는 경우만 서버에 전송
// signed : 쿠키의 암호화 결정 ( req.signedCookies 객체에 들어있다.)
httpOnly : true ,
maxAge : 60 * 1000 , //1분
signed : true
}
app . get ( '/' , ( req , res ) => {
res . render ( "index" );
});
app . listen ( PORT , () => {
console . log ( `http://localhost: ${ PORT } ` );
});
ejs ▽
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Document </ title >
</ head >
< body >
< a href = "/setCookie" > 쿠키 설정 </ a >
< a href = "/checkCookie" > 쿠키 확인 </ a >
< a href = "/delCookie" > 쿠키 제거 </ a >
</ body >
</ html >
app . get ( '/setCookie' , ( req , res ) => {
//쿠키이름 쿠키 값 옵션
res . cookie ( 'myCookie' , 'myVal' , cookieConfig );
res . send ( 'set cookie' );
})
app . get ( '/checkCookie' , ( req , res ) => {
//쿠키이름 쿠키 값 옵션
// res.cookie('myCookie', 'myVal', cookieConfig);
res . send ( req . signedCookies );
})
app . get ( '/delCookie' , ( req , res ) => {
res . clearCookie ( 'myCookie' , 'myVal' , cookieConfig );
res . send ( 'clear cookie' )
})
위 코드를 맨위의 코드 get과 listen 사이에 넣어서 사용
Session
웹 서버에 저장되는 쿠키 웹 브라우저를 통해 접속한 시점부터 연결을 끝내는 시점까지의 시간 동안 일련의 요구를 하나의 상태로 보고 그 상태를 유지 시킨다.
[동작 방식]
1. 클라이언트가 서버에 접속 시 세션 id를 발급 받음
2. 클라이언트는 세션 id에 대해 쿠키를 사용해서 저장하고 가지고 있다
3. 클라이언트는 서버에 요청할 때, 이 쿠키의 세션 id를 서버에 전달해서 사용합니다.
4. 서버는 세션 id를 전달받아서 별다른 작업 없이 세션 id로 세션에 있는 클라이언트 정보를 가져옴
5. 클라이언트 정보를 가지고 서버 요청을 처리여 클라이언트에게 응답
npm i express-session를 입력하여 설치 후 사용