* 스칼라 벡터에 대한 구조체 정의


 cvPoint

 int x,y

 영상 내 한 점의 위치

 cvPoint2D32f

 float x,y

 2차원 실수 공간에서의 좌표

 cvPoint3D32f

 float x,y,z

 3차원 실수 공간에서의 좌표

 cvSize

 int width,height

 영상의 크기

 cvScalar

 double val[4]

 RGB값


openCV는 주로 IplImage 데이터 타입을 사용한다. IplImage는 '영상'이라고 부르는 것을 표현하는 데이터 타입이다. 


이러한 IplImage 데이터타입은 cvArr로 부터 상속된 구조를 갖는다 .cvArr->cvMat->IplImage


OpenCV에서 행렬은 32비트 실수형 1채널(CV_32FC1), 부호없는 8비트 정수형 3채널(CV_8UC3) 등 여러 데이터 타입으로 구성될 수 있다. 


이러한 행렬을 만드는 함수는 cvCreateMat(int rows,int cols,int type)을 쓴다. 


행렬을 만들고 나서 행렬의 속성을 알아보기 위해서 cvGetElemType(), cvGetDims(), cvGetDimSize()등의 함수를 사용한다.



* 행렬 데이터 접근하기 


1. 간편한 방법


CV_MAT_ELEM() 과 CV_MAT_ELEM_PTR() 매크로를 이용한다 .


2. 엄격한 방법


cvPtr*D 또는 cvGet*D 형태의 함수를 사용한다.


ex)  uchar* cvPtr1D(const CvArr* arr,int idx0, int* type=NULL);

ex)  double cvGetReal1D(const CvArr* arr,int idx0);


cvGet*D와 유사한 cvSet*D 형태의 함수는 행렬 또는 영상의 특정 위치 원소값을 설정하는 함수이다.


ex) void cvSetReal1D(CvArr* arr, int idx0, double value);

    void cvSetReal2D(CvArr* arr, int idx0, int idx1, double value);


3.적절한 방법


앞서 행렬 데이터를 조작하는 다양한 접근 함수를 알아보았지만 거의 사용하지 않는다.

보통 행렬의 데이터를 접근할 때, 포인터를 통한 접근을 우선시한다.


float sum(const CvMat* mat)

{

float s = 0.0f;


for(int row=0;row<mat->rows;row++)

{

const float* ptr(const float*)(mat->data.ptr+row*mat->step);


for(col=0;col<mat->cols;col++)

s+=*ptr++;

}


return(s);

}



IplImage 구조체 


중요변수 -> width, height, depth, nChannels, origin, dataOrder,widthStep


nChannels ->픽셀의 채널 수. 

depth -> 데이터의 타입.

origin -> IPL_ORIGIN_TL(0), IPL_ORIGIN_BL(1) 중 하나를 가질 수 있다. 영상에서 좌표의 원점이 좌상단에 위치하는 지 좌하단에 위치하는지를 가리킨다. 

dataOrder  -> IPL_DATA_ORDER_PIXEL 또는 IPL_DATA_ORDER_PLANE 중에 하나를 지정한다 . 이 값이 IPL_DATA_ORDER_PIXEL이면 다중채널값을 차례대로 가지고 있고 , 일반적인 인터리브 방식이다 . 만약 dataOrder가 IPL_DATA_ORDER_PLANE값을 가지면 각 채널 별로 따로 픽셀값이 저장된다.(일반적으로 인터리브 방식사용한다. 행의 개수 = 영상의 높이, 각 행에서는 각 채널값이 교차된 순서로 나타난다.)

widthStep -> 한 행이 실제로 차지하고 있는 바이트 수.

imageData -> 영상 데이터의 시작 주소를 가리킨다. 


#관심영역(roi)  --> 영상 내부에 roi가 설정되어 있을 경우, 영상을 다루는 함수는 영상 전체에 대하여 동작하는 대신 roi로 설정된 영역에서만 동작한다. 모든 opencv 함수는 roi 설정 여부를 스스로 판단하여 동작한다 .



* 영상데이터 접근하기


OpenCV 라이브러리가 영상 처리와 관련된 다양한 함수들을 제공하지만 실제 작업에서 필요한 모든 함수들을 완벽하게 제공할 수는 없다. 예를 들어, 3채널 HSV 영상에서 색상값은 그대로 둔 채 채도와 명도값을 모두 255로 설정하는 작업은 행렬을 이용하여 영상자체를 가리키는 포인터를 이용하여 수행하는것이 효과적이다.


HSV 영상에서 "S"와 "V"에 해당하는 값을 최대화


void saturate_sv(IplImage* img)

{

for(int y=0;y<img->height;y++)

{

uchar* ptr = (uchar*)(img->imageData + y*img->widthStep);


for(int x=0;x<img->width;x++)

{

//ptr [3*x]는 h값을 나타낸다.

ptr[3*x+1] = 255;

ptr[3*x+2] = 255;

}

}



* roi를 설정하는 두가지 방법.


1. void cvSetImageROI(IplImage* image,CvRect rect);

   void cvResetImageROI(IplImage* image);


#include 
#include 

int main()
{
      IplImage* src = cvLoadImage("~~",1);

      cvSetImageROI(src, cvRect(x,y,width,height));
      cvAddS(src, cvScalar(add),src);
      cvRestImageROI(src);

      cvNamedWindow("Roi_Add", 1);
      cvShowIamge("Roi_Add", src);
      cvWaitKey();

      cvReleaseImage(&src);
      cvDestroyWindow("Roi_Add");
}
      return 0;
}
      

2. widthStep을 이용하여 관심 영역을 처리하는 대체방법

IplImage *sub_img = cvCreateImageHeader(
     cvSize(
           interest_rect.width,
           interest_rect.height
     ),
     interest_img->depth,
     interest_img->nChannels
);

sub_img->origin = interest_img->origin;

sub_img->widthStep = interest_img->widthStep;

sub_img->imageData = interest_img->imageData + interest_rect.y * interest_imag->widthStep + interest_rect.x * interest_img->nChannels;

cvAddS(sub_img,cvScalar(1),sub_img);

이하 다양한 함수들은 생략하고 필요할 때마다 참조하여 공부한다

아래는 연습문제 예제이다. 개인적으로 2,4,5,6,7 번이 중요하다고 생각한다.

#include

#include #include typedef struct my_struct{ int a; CvPoint b; CvRect c; }my_struct; void write_my_struct(CvFileStorage* fs, const char* name, my_struct *ms); void read_my_struct(CvFileStorage* fs, my_struct *ms); int main() { /01번 CvMat* mat = cvCreateMat(1,1,CV_32FC3); CvMat* dst = cvCreateMat(1,1,CV_32FC3); *((float*)CV_MAT_ELEM_PTR(*mat, 0, 0)) = 0; //a cvAbs(mat, dst); //b CvMat* noise = cvCreateMat(10, 1, CV_64FC1); CvRNG rng[] = { cvRNG(time(NULL)), cvRNG(time(NULL)) }; cvRandArr(rng, noise, CV_RAND_NORMAL, cvScalarAll(0), cvScalarAll(0)); //c,d CvPoint((int)CvPoint2D32f(3.0, 2.0).x,(int)CvPoint2D32f(3.0, 2.0).y); cvPoint2D32f((float)cvPoint(3,2).x,(float)cvPoint(3,2).y); / /02번 - 100*100 3채널 2차원 행렬 생성후 원그리고 출력. CvMat* mat = cvCreateMat(100,100,CV_8UC3); cvSet(mat, cvScalarAll(255)); cvCircle(mat, cvPoint(50, 50), 40, CV_RGB(0, 0, 250)); cvNamedWindow("Drawing Graphics", CV_WINDOW_AUTOSIZE); cvShowImage("Drawing Graphics", mat); cvWaitKey(0); / /04번- 100*100 3채널 RGB영상을 생성하고 흰색초기화후 포인터 연산을 통한 녹색사각형 출력 IplImage* src = cvCreateImage(cvSize(100, 100), , 3);; cvSet(src, cvScalarAll(255)); for (int i = 20; i < 40; i++){ uchar* ptr = (uchar*)(src->imageData+i*src->widthStep); for (int j = 5; j < 20; j++){ ptr[3 * j] = 0; ptr[3*j+1] = 150; ptr[3 * j + 2] = 0; } } cvNamedWindow("Drawing Graphics", CV_WINDOW_AUTOSIZE); cvShowImage("Drawing Graphics", src); cvWaitKey(0); / /05번 - 관심영역연습. IplImage* src = cvCreateImage(cvSize(210, 210), IPL_DEPTH_8U, 1); cvSet(src, cvScalarAll(0)); for (int i = 0; i < 110; i += 10){ cvSetImageROI(src, cvRect(i, i, 210-2*i, 210 - 2 * i)); cvSet(src, cvScalarAll(2 * i)); } cvResetImageROI(src); cvNamedWindow("5번", 1); cvShowImage("5번", src); cvWaitKey(); cvReleaseImage(&src); cvDestroyWindow("5번"); / /6번 - cvNot 활용. IplImage* src = cvLoadImage("C:/Users/Jonghwan123/Documents/카카오톡 받은 파일/opencv.jpg"); IplImage* dst1 = cvCreateImageHeader(cvSize(20,30), src->depth, src->nChannels); IplImage* dst2 = cvCreateImageHeader(cvSize(20,30), src->depth, src->nChannels); dst1->origin = src->origin; dst2->origin = src->origin; dst1->widthStep = src->widthStep; dst2->widthStep = src->widthStep; dst1->imageData = src->imageData + 10*src->widthStep + 10*src->nChannels; dst2->imageData = src->imageData + 60*src->widthStep + 50 *src->nChannels; cvNot(dst1,dst1); cvNot(dst2,dst2); cvNamedWindow("6번", 1); cvShowImage("6번", src); cvWaitKey(); / /7번 - 임계값을 구하고 임계값을 통한 cvCmp cvSubS 활용. IplImage* src = cvLoadImage("C:/Users/Jonghwan123/Documents/카카오톡 받은 파일/opencv.jpg"); IplImage* dst1 = cvCreateImage(cvSize(src->width,src->height),src->depth,1); IplImage* dst2 = cvCreateImage(cvSize(src->width,src->height),src->depth,1); IplImage* dst3 = cvCreateImage(cvSize(src->width,src->height),src->depth,1); cvSplit(src, dst1, dst2, dst3, NULL); IplImage* clone1 = cvCreateImage(cvSize(dst1->width, dst1->height), dst1->depth, 1); IplImage* clone2 = cvCreateImage(cvSize(dst1->width, dst1->height), dst1->depth, 1); double min = 0; double max = 0; cvMinMaxLoc(dst1, &min, &max, NULL, NULL, NULL); unsigned char thresh = (unsigned char)((max + min) / 2.0)+100; cvSet(clone1, cvScalar(thresh)); cvSet(clone2, cvScalar(0)); cvCmp(dst1, clone1, clone2, CV_CMP_GE); cvSubS(dst1, thresh / 2, dst1, clone2); cvNamedWindow("7번", 1); cvShowImage("7번", clone2); cvWaitKey(); / /8번 my_struct ms = { 1, { 20, 30 }, { 20, 30, 10, 20 } }; //CvFileStorage* wfs = cvOpenFileStorage("cfg.xml", 0, CV_STORAGE_WRITE); CvFileStorage* rfs = cvOpenFileStorage("cfg.xml", 0,CV_STORAGE_READ); //write_my_struct(wfs, "jonghwan",&ms); //CvSeq* s = cvGetFileNodeByName(rfs, 0, "jonghwan")->data.seq; //CvFileNode* filenode = (CvFileNode*)cvGetSeqElem(s,0); read_my_struct(rfs, &ms); / } //8번함수1 void write_my_struct(CvFileStorage* fs, const char* name, my_struct *ms){ cvWriteInt(fs, "a", ms->a); cvStartWriteStruct(fs, "b", CV_NODE_SEQ); cvWriteInt(fs, 0, ms->b.x); cvWriteInt(fs, 0, ms->b.y); cvEndWriteStruct(fs); cvStartWriteStruct(fs, "c", CV_NODE_SEQ); cvWriteInt(fs, 0, ms->c.x); cvWriteInt(fs, 0, ms->c.y); cvWriteInt(fs, 0, ms->c.width); cvWriteInt(fs, 0, ms->c.height); cvEndWriteStruct(fs); cvReleaseFileStorage(&fs); //cvWrite(fs, "b", &ms->b); //cvWrite(fs, "c", &ms->c); } //8번함수2 void read_my_struct(CvFileStorage* fs, my_struct *ms){ int a = cvReadIntByName(fs, 0, "a", 5); CvSeq* b = cvGetFileNodeByName(fs, 0, "b")->data.seq; int bx = cvReadInt((CvFileNode*)cvGetSeqElem(b, 0)); int by = cvReadInt((CvFileNode*)cvGetSeqElem(b, 1)); CvSeq* c = cvGetFileNodeByName(fs, 0, "c")->data.seq; int cx = cvReadInt((CvFileNode*)cvGetSeqElem(c, 0)); int cy = cvReadInt((CvFileNode*)cvGetSeqElem(c, 1)); int width = cvReadInt((CvFileNode*)cvGetSeqElem(c, 2)); int height = cvReadInt((CvFileNode*)cvGetSeqElem(c, 3)); //printf("%d", frame_count); }


'프로그램 > opencv' 카테고리의 다른 글

high gui  (0) 2015.07.08
opencv 기초  (2) 2015.07.03
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요


1. 우선 npm install 명령어로 paypal rest api sdk 모듈을 설치해준다.



2. 환경설정을 해준다.(자신만의 config.js 파일을 만든다)



3. 필자는 MVC 패턴으로 config폴더에 route.js 폴더를 만들고 라우팅 해주었다.



4. controllers 폴더내에 paypalController.js를 생성하고 paypalCreate, paypalExecute 함수를 작성한다.


코드는 영화예매 사이트 결제에 관한 것으로 다른 로직은 무시하고 payment라는 객체를 생성하고 paypal.payment.create로 paypal 결제를 생성한다는 점과 paypal.payment.execute에서는 session에 저장해 놓은 paymentId를 parameter로 결제 실행을 한다는 점을 유의하여 보면 되겠다.



cf. 추가적으로 invoice생성을 하여 결제 완료시 invoice를 얻어와서 db처리를 해줄 수도 있는데 이는 https://github.com/paypal/PayPal-node-SDK/를 참조하길 바란다.


5. 뷰를 생성한다.


뷰 생성시에는 아까 라우팅했던 /paypalCreate 을 호출할 때 보내줄 인자에 신경을 써야한다.

즉, paypal.payment.create가 정상적으로 결제를 생성하려면 payment 객체가 정상이여야 하는데 

payment정보는 /paypalCreate를 호출할 때 보내준 parameter에 의해 결정된다.


반드시 포함해야 하는 인자를 알려주는 아래 폼을 보자.



method, amount, currency는 반드시 포함되어야 한다.

method는 paypal or credit 신용카드로 하여 credit일 때에는 신용카드 정보를 같이 넘겨주어 위의 paypalController.js에서 소개한 방법대로 처리하면 되겠고,

amount는 총 액이다.

currency는 통화단위이다.



'프로그램 > node.js' 카테고리의 다른 글

node.js와 paypal 결제시스템 연동(1)  (0) 2015.05.13
passport-local  (0) 2015.03.27
인코딩문제(iconv를 통한 해결)  (0) 2015.03.27
node.js http request 모듈  (0) 2015.03.27
node-gyp 관련에러  (0) 2015.03.27
npm install 관련 오류  (0) 2015.03.27
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

우선 http://bcho.tistory.com/920 이걸 본다.

그리고 http://passportjs.org/guide/ 이걸본다. 


https://github.com/manjeshpv/node-express-passport-mysql   mysql+passport..


여기서 이해 안되는 건 1)serialize와 deserialize인데 도대체 done 에 user.id 의 정체는 무엇인가?


1)serializeUser 메서드에서는 function(user,done)을 이용해서 session에 저장할 정보를 done(null,user)과 같이 두번째 인자로 넘기면 된다. 이때 user로 넘어오는 정보는 앞의 LocalStrategy 객체의 인증함수에서 done(null,user)에 의해 리턴된 값이 넘어온다.


2) req.flash 가  express 3.0부터 deprecated 되어 connect-flash 모듈을 깔고 require('connect-flash') 을 해주어야 한다.

   그 다음 app.use(flash()); 을 해줘야 한다. 


+ 여기서 오류가 났다. req.flash() requires sessions 오류인데..

공식 홈에서는 


Alternatively, the flash message can be set specifically.

passport.authenticate('local', { failureFlash: 'Invalid username or password.' });

successFlash option is available which flashes a success message when authentication succeeds.

passport.authenticate('local', { successFlash: 'Welcome!' });

이렇게 가이드를 하고 있다.  req.flash()는 Express 3.0에서는 deprecated 되어 connect-flash 모듈을 설치해야만 사용이 가능하다.

npm에서 connect-flash 모듈을 검색한 후 공식 사용설명서를 보면 이렇게 안내하고 있다.

var flash = require('connect-flash');
var app = express();

app.configure(function() {
  app.use(express.cookieParser('keyboard cat'));
  app.use(express.session({ cookie: { maxAge: 60000 }}));
  app.use(flash());
});


이런식으로 설정후에 사용한다. 주의사항은 app.configure flash  설정 부분이 app.use(app.router) 설정 위에 위치 해야한다는 것이다.

그렇지 않으면 object # incomingmessage has no method 'flash' 와 같은 오류가 발생한다. 


3) ajax 로그인을 구현하고자 할 때..

bootstarp과 함께 jqbootstarpvalidation plug-in을 써서 ajax로 로그인을 구현하였다. ajax로 로그인을 구현하고자 할 때에는 공식홈에서 가이드 하고 있는 custom callbak을 이용하였다.

Custom Callback

If the built-in options are not sufficient for handling an authentication request, a custom callback can be provided to allow the application to handle success or failure.

app.get('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/users/' + user.username);
    });
  })(req, res, next);
});

In this example, note that authenticate() is called from within the route handler, rather than being used as route middleware. This gives the callback access to the req and res objects through closure.

If authentication failed, user will be set to false. If an exception occurred, err will be set. An optional infoargument will be passed, containing additional details provided by the strategy's verify callback.

The callback can use the arguments supplied to handle the authentication result as desired. Note that when using a custom callback, it becomes the application's responsibility to establish a session (by callingreq.login()) and send a response.

 Custom CallBack을 이용한다. 모든 클라이언트 요청은 동기 또는 비동기로 나눌 수 있다. 비동기 방식은 ajax로 구현을 많이 하는데 모든 저명한 모듈이나 플러그인들은 ajax를 지원하는 것 같다. 


클라이언트 단에서는 


 $('#login_form').find('input,select,textarea').not('[type=submit]').jqBootstrapValidation({

        submitSuccess: function ($form, event) {

          $.ajax({

            type: 'POST',

            url: $form.attr('action'),

            data: $form.serialize(),

            success: function(data)

            { 

                

              // just to confirm ajax submission

              $('#login_message').show(100);

              document.getElementById('login_message').innerHTML=data.message;




              //만약 로그인에 성공하면 page replace!

              if(data.type) {

                  var URL = '/user/'+data.alias;

                  location.replace(URL);

              }
            }

          });

          // will not trigger the default submission in favor of the ajax function

          event.preventDefault();

        }


이런식으로 요청을 넣고, 서버단에서는 CustomCallback을 이용해서 ajax에 응답한다. 여기서 중요한 것은 req.logiin인데 이 부분이 세션에 저장된 value를 얻어오고 또 활용할 수 있는 부분이므로 이에 주의해서 코딩할 필요가 있다. 

'프로그램 > node.js' 카테고리의 다른 글

node.js와 paypal 결제시스템 연동(1)  (0) 2015.05.13
passport-local  (0) 2015.03.27
인코딩문제(iconv를 통한 해결)  (0) 2015.03.27
node.js http request 모듈  (0) 2015.03.27
node-gyp 관련에러  (0) 2015.03.27
npm install 관련 오류  (0) 2015.03.27
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

node.js에서의 인코딩은 iconv 모듈을 사용함으로써 간단히 해결할 수 있다.


학교강의 평가 게시판을 만들때 학교 api가 euc-kr으로 encoding 되어 있어 이를 utf-8 로 변환해 주어야 했다.


iconv 를 설치하고 다음과 같이 선언한다.


  //인코딩 모듈

var Iconv  = require('iconv').Iconv;

var euckr2utf8 = new Iconv('EUC-KR', 'UTF-8');


//받아온 데이터의 euc-kr 형식을 ut8로 변환

var data = new Buffer(body, 'binary');

var data_utf8 = euckr2utf8.convert(data).toString();


이때 버퍼에 담지 않고 바로 euckr2utf8을 사용하면 오류가 난다... 


주의사항)  iconv 모듈 설치시 오류가 나는 경우!


node-gyp모듈이 동작하지 않는 경우가 있는데  이는 github에서  node-gyp를 검색하여 가이드를 참고하면 된다.

(intallation 부분을 참고)

파이썬과  visual studio를 설치해야만 작동이 된다.

'프로그램 > node.js' 카테고리의 다른 글

node.js와 paypal 결제시스템 연동(1)  (0) 2015.05.13
passport-local  (0) 2015.03.27
인코딩문제(iconv를 통한 해결)  (0) 2015.03.27
node.js http request 모듈  (0) 2015.03.27
node-gyp 관련에러  (0) 2015.03.27
npm install 관련 오류  (0) 2015.03.27
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

node.js 가 클라이언트가 되어 서버에 요청을 보내는 경우 http request 모듈을 이용한다 .


예를 들어 학교 api에 정보를 요청하는 경우가 있다. 



//request 모듈 선언 

var request = require('request');


//api에 http request


var headers = {

    'User-Agent':       'Super Agent/0.0.1',

    'Content-Type':     "application/xml"

}

 //api get options.

 var options = {

 url : 'http://wise.uos.ac.kr/uosdoc/api.ApiUcrCultTimeInq.oapi',

 method:'GET',

 headers:headers,

 encoding:'binary',

 qs: {'apiKey': '201501195EQW98965','year':'2014','term':'A10','subjectDiv':'""'}

 };

console.log("Let's Start courseLoad");

//request 동작. 

request(options, function (error, response, body) {

    if(error) console.log("에러에러(wise 점검 및 인터넷 연결 안됨)");

    if (!error && response.statusCode == 200) {

    

     //받아온 데이터의 euc-kr 형식을 ut8로 변환

     var data = new Buffer(body, 'binary');

    

     var data_utf8 = euckr2utf8.convert(data).toString();

    

    

     //받아온 강의 데이터 xml 형식을 json으로 변환.

     var course_array = xm.load(data_utf8).root.mainlist.list;

     var dataSet= new Array(course_array.length);

     //받아온 데이터를 테이블 형식에 맞게  Array형식으로 변환.

for(var i=0;i<course_array.length;i++){

 dataSet[i]= new Array(4); 

 dataSet[i][0]=course_array[i].sub_dept.$cd;

 dataSet[i][1]=course_array[i].subject_div.$cd;

 dataSet[i][2]=course_array[i].subject_nm.$cd;

 dataSet[i][3]=course_array[i].prof_nm.$cd;

 dataSet[i][4]='<a href="/evaluate/'+course_array[i].subject_nm.$cd+"/"+course_array[i].prof_nm.$cd+'" class="btn btn-primary btn-xs" data-title="evaluate"><span class="glyphicon glyphicon-pencil"> 평가하기</span></a>'

};

    

    

     //Array를  클라이언트로 전송.

res.send(dataSet);

    

    }

});




여기서 중요한 것은 option 지정 부분이다. 


기본적인 내용으로 들어가서 http request 가 도대체 무엇인가를 알아야 하겠다.


HTTP_request.png

http request란 간단하게 이러한 그림으로 설명할 수 있다. 브라우저(클라이언트)에서 서버에 요청을 보내고 서버에서는 그 요청을 처리하여 뿌려주는 것이다. 그렇다면 우리가 구축하는 웹서버란 무엇일까? 


웹서버란  http(hypertext transfer protocol)프로토콜을 기반으로 웹페이지에 해당하는 파일을 클라이언트에게 전달하는 역할을 하는 서버이다.

node.js로 http프로토콜(통신규약)을 토대로 지금 껏 웹서버를 구축해 온 것이다. 


그렇다면 content-type Field는 무엇인가?  http는 클라이언트와 서버가 일정하고 예측가능한 방식으로 정보를 교환하고 상호작용 할 수 있도록 하는 Method와 Header의 집합을 정의하고 있다 . 


여기서 문제는 개발자가 직접 위의 코드와 같이 request 코드를 작성할 때 content-type option을 정확하게 이해하고 작성해야만 한다는 것이다. 아직은 이해가 잘 이해 되지 않는다.. get 방식과 post 방식에서의 content-type 설정? get 방식에서는 content-type을 설정하지 않고 요청을 보내는 것인가? post 방식에서만 content-type을 설정하여 보내는 데이터의 타입과 인코딩을 지정해 주는 것인가 ? 아직 잘 모르겠다. 일단 추후에 다시 공부한뒤 다시 포스팅을 해야겠다. 할일이 많다 ...



1. HTTP Header Content-Type Field란?



Content-Type이란 말 그대로 사용자 요청과 응답 메시지 타입을 뜻하며, 크게 Discrete-Type 과 Composite-Type으로 나뉩니다.


또한, 문법으로 아래와 같은 형태를 가집니다.




Content-Type(필드명): text(타입)/plain(서브타입); charset=us-ascii(파라메터)


Discrete-Type: 그 자체로 어떤 의미를 가지고 있는 Content-Type을 나타낸다.


예) "text" / "image" / "audio" / "video" / "application" / extension-token


Composite-Type: Discrete-Type 혹은 Composite-Type의 개체 여러 개가 복합되어 만들어진 타입을 나타낸다.


예)  "message" / "multipart" / extension-token




MIME Type 참고 사이트


http://www.iana.org/assignments/media-types/index.html






즉, 아래 그림의 Accept 필드는 응답 시 브라우저가 허용할 수 있는 메시지 타입을 가리키며, Content-Type은 그에 따른 응답 메시지 타입을 나타내는 것입니다.








2. HTTP란?



HTTP란 간단히 말해 웹 브라우저와 웹서버 간에 메시지 교환 프로토콜입니다. 즉, 일종의 대화 규칙이며, 교환 방식은 복잡한 바이너리 데이터가 아닌 단순 텍스트를 통해 이루어집니다.


위에서 설명한 Content-Type의 응답 메시지(html, xml, 등..)또한, 단순 텍스트로 교환되며, 


만약 누군가가 주고받는 네트웍 패킷을 가로채 볼 수 있다면, 메시지 내용이 그대로 보이게 되므로 보안상 치명적 결과를 가져올 수 있는 상황입니다.


즉, 컨텐츠 보안이 필요한 경우에는 HTTPS 프로토콜을 사용하여, 주고받는 네트웍 패킷을 알고리즘을 통해 모두 암호화 해야 할 필요가 있습니다.




3. HTTPS란?



HTTPS는 HTTP와 같은 통신 프로토콜이며, 쓰임새(메시지 전송) 또한, HTTP와 거의 흡사합니다.


하지만 HTTPS는 앞서 설명했던 HTTP의 취약점을 보완하기 위해 주고받는 모든 메시지를 암호화하며, 암호화 방식에 쓰이는 Key의 종류로는 크게 대칭과 비대칭 둘로 나뉘게 됩니다.


간단히 동작원리에 대해 설명하자면, 클라이언트(웹 브라우저)와 서버(웹서버)가 서로 교환한 세션키(대칭키)로 주고받는 모든 컨텐츠 내용을 암호화합니다.


즉, 중간에 네트웍 패킷을 가로챈다 해도 암호화된 내용이 노출되므로 보안상 안전하며, 공유된 세션키(대칭키)를 모르는 상황에서 암호화를 푼다는 것은 모든 경우의 키를 대입해야 한다는 말이 됩니다.


만약 1024 비트(보통은 128비트 암호화)의 암호화라면, 평균적으로 2의 512승을 대입해야하며, 이것은 2475880078570760000000000000.00이라는 수를 대입해야 한다는 뜻과 같습니다.


이 숫자는 아무리 빠른 컴퓨터(현재까지 나온..)라 할지라도 약 몇 천 년에 걸려 계산되어야 할 것 입니다.



위에서 설명한 내용 중 세션키 교환 동작과 같은 더 자세한 설명은 다음 포스트 주제인 SSL 동작원리에서 다루도록 하겠습니다.

'프로그램 > node.js' 카테고리의 다른 글

passport-local  (0) 2015.03.27
인코딩문제(iconv를 통한 해결)  (0) 2015.03.27
node.js http request 모듈  (0) 2015.03.27
node-gyp 관련에러  (0) 2015.03.27
npm install 관련 오류  (0) 2015.03.27
passport에서 세션과 쿠키  (0) 2015.03.27
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

node.js npm으로  package를 설치하다보면 자꾸 node-gyp 관련하여 오류가 난다...


npm 공식사이트에서 설명하는대로 python도 설치하였고,

visual studio 2012 도 설치 하였지만 계속오류가 난다... 


이와 관련하여 node-gyp configure ? 이것도 오류 ..

뭐가 뭔지 아직은 모르겠다. 


iconv 설치했을 때 해결했다고 생각했으나 socket.io 를 설치할 때 아직도 오류가 난다. 


우선은 npm install socket.io -f  

force 옵션을 주어 설치하였다. 구글링을 해보면 g옵션을 주라하고 

오류와 관련하여  appdata/roaming/npm 이라는 경로가 뜨는데 대체 뭔지 하나도 모르겠다. 


추후 찾아봐야 할 것 


1)  appdata/roaming/npm 은 어떤 경로이며 왜 환경변수 path에 설정되있는 것일까?

2) node-gyp configure은 무슨 명령인가?

3) -g 옵션은 무슨 옵션인가 ..

4) 왜 자꾸 package 설치시 오류가 나는 것일까 ?

'프로그램 > node.js' 카테고리의 다른 글

인코딩문제(iconv를 통한 해결)  (0) 2015.03.27
node.js http request 모듈  (0) 2015.03.27
node-gyp 관련에러  (0) 2015.03.27
npm install 관련 오류  (0) 2015.03.27
passport에서 세션과 쿠키  (0) 2015.03.27
node.js에서의 module.exports와 exports의 차이?  (0) 2015.03.19
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

npm install시에 ENOENT, stat appdata \ roaming \npm 

오류가 뜨는 경우가 있다.


이 경우는 github node 에서 이렇게 가이드를 하고 있다.


windows: Create npm folder in AppData directory
Create the empty npm folder in Roaming\Appdata so that
non-Administrator users have a place to store global packages.
This fixes the error Error: ENOENT, stat error that occurs
when a user tries to run the npm install <package> command.


이 경우에는 npm이라는 빈폴더를 생성해야 한다. 권한을 갖지 않은 사용자가 global packages를 저장하기 위한 공간을 갖기 위해서라고 한다.  -g 옵션을 주어 설치하는 모듈은 모두 이 장소에 설치된다.
 
또한 이 경로에 있는 모듈을 사용할 때에는 NODE_PATH 환경변수를 잡아주어야 한다.
ex) NODE_PATH=C:\User\사용자명\appdata\roaming\npm\node_modules


'프로그램 > node.js' 카테고리의 다른 글

node.js http request 모듈  (0) 2015.03.27
node-gyp 관련에러  (0) 2015.03.27
npm install 관련 오류  (0) 2015.03.27
passport에서 세션과 쿠키  (0) 2015.03.27
node.js에서의 module.exports와 exports의 차이?  (0) 2015.03.19
node.js 유용한 모듈(n가지)  (0) 2015.02.16
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

passport에서는 serializeUser 와 deserializeUser를 통해 login 유지를 구현하게 된다.


serializeUser시 session에 유저정보를 저장하고 deserializeUser시 session에서 유저정보를 가져와 http request 객체에 user라는 key에 담아 보내준다.


deserializeUser는 매 페이지마다 실행되기 때문에 페이지를 띄우면(get 방식) req.user에 담긴 유저정보를 사용해 crud 웹을 구현할 수 있게되는 것이다.


client 쪽에서는 cookie를 통해 session에 접근 할 수 있는 key를 브라우저에 가지고 있게 되며, cookie가 만료되어서 파기되면 session도 함께 지워진다. 그래서 express + passport를 통해 사용자 인증을 구현하기 위해서 cookie의 maxage 설정에 주의할 필요가 있다.


아래는 공식홈에서 가이드하고 있는 내용이다.

The server will store the pertinent information in the session object, and create a session ID which it will send back to the client in a cookie. When the client sends back the cookie, the server can simply look up the session object using the ID. So, if you delete the cookie, the session will be lost.


(서버는 session object에 유저정보를 유지하는데 이때 session Id를 client에 session cookie 값으로 보내준다. 클라이언트는 이를 이용해 session object를 찾고 이를 리턴 받게 되는 것이다. node.js에서는 deserializeUser를 할때 이 session cookie값을 이용해 session obejct를 searching하고 return 하는 것으로 볼 수 있다. 이는 passport 공식홈에서도 잘 설명해주고 있다. 


Sessions

In a typical web application, the credentials used to authenticate a user will only be transmitted during the login request. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.

via a cookie set이라는 부분이 있다. session은 생성되고 maintain된다 user browser의 cookie set을 통해서)

'프로그램 > node.js' 카테고리의 다른 글

node-gyp 관련에러  (0) 2015.03.27
npm install 관련 오류  (0) 2015.03.27
passport에서 세션과 쿠키  (0) 2015.03.27
node.js에서의 module.exports와 exports의 차이?  (0) 2015.03.19
node.js 유용한 모듈(n가지)  (0) 2015.02.16
모듈 path 관리 기법.  (0) 2015.02.12
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

출처 - http://b.mytears.org/2009/03/1848)



HTTP(Hyper text transfer protocol)로 페이지를 요청하기 위해서는 다음과 같은 방법을 사용합니다.

METHOD URI VERSION

많은 옵션이 붙을 수 있지만 이정도가 페이지를 요청하기 위한 기본 쿼리라고 생각하시면 됩니다. METHOD는 ‘GET’, ‘POST’, ‘HEAD’, ‘OPTION’ 정도가 될 수 있겠고, URI는 PATH + QUERY STRING이라고 생각하시면 되겠습니다.

자 그럼 이걸 응용해 봅시다.

GET /index.php HTTP/1.1

위 코드는 /index.php 페이지를 HTTP/1.1 프로토콜을 사용해서 호출하겠다는 얘기입니다. 여기에 값을 넘겨주려면 QUERY STRING을 사용하면 됩니다.

아래와 같이 var1이란 변수에 1234, var2란 변수에 2345란 값을 담아서 페이지를 호출해봅시다.

GET /index.php?var1=1234&var2=2345 HTTP/1.1

간단하죠. 단 URI의 길이에는 제약이 있기 때문에 이런 방식을 사용할 경우 긴 데이터를 넘겨줄 순 없습니다.

긴 데이터를 넘겨줄 때는 POST를 사용하게 되는데요. POST를 사용해서 값을 넘겨줄 때는 아래와 같은 코드를 사용하게 됩니다.

POST /index.php HTTP/1.1 Content-type: application/x-www-form-urlencoded Content-length: 19 var1=1234&var2=2345

Content-length는 넘겨줄 값의 길이를 의미합니다. 간단하죠. 뭐하튼 값을 넘겨주는 데는 GET과 POST 방식을 사용할 수 있고, GET 방식에서는 값을 URI에 붙여서 보내준다는 얘기를 하고 싶었습니다.

그런데 브라우져마다 GET 방식으로 값을 넘겨줄 때 사용하는 인코딩이 동일하지가 않네요. 예전에 ‘웹 서비스와 UTF-8‘이란 글에 적어놨듯이 RFC2718에서는 URI를 UTF-8로 인코딩할 것을 권고하고 있습니다.

그렇다면

  1. euc-kr로 인코딩된 페이지에서 다른 페이지로 값을 GET 방식을 사용해서 넘겨준다면 어떤 인코딩을 사용해야할까요?
  2. utf-8로 인코딩된 페이지에서 다른 페이지로 값을 GET 방식을 사용해서 넘겨준다면 어떤 인코딩을 사용해야할까요?
  3. 만약 url에 직접 query string을 붙여서 페이지를 요청할 경우에는 어떤 인코딩을 사용해야할까요?

URL을 정의하고 있는 RFC2396에서는 URI를 PATH+QUERY 로 정의하고 있고, 이를 확장한 RFC2718에서 URI를 UTF-8로 인코딩하자고 했으니 위의 모든 경우에서 URI는 utf-8로 인코딩되어야 맞습니다. (단 1번의 경우에는 %인코딩을 사용해서 값을 Escape시켜줘야겠죠.)

하지만 재앙의 근원 Internet explorer에서는 3번과 같은 상황일 때 query string을 로컬 인코딩으로 인코딩해버립니다. [1] ajax를 사용할 때 생기는 문제에 비교하면 이 정도는 애교입니다.

  1. utf-8 페이지에서 ajax + get으로 값을 전송합니다. 어떤 인코딩으로 값이 전송될까요?
  2. euc-kr 페이지에서 ajax + get으로 값을 전송합니다. 어떤 인코딩으로 값이 전송될까요?
  3. utf-8 페이지에서 ajax + post로 값을 전송합니다. 어떤 인코딩으로 값이 전송될까요?
  4. euc-kr 페이지에서 ajax + post로 값을 전송합니다. 어떤 인코딩으로 값이 전송될까요?

3, 4번의 경우 Internet explorer를 쓰건 safari, firefox등을 쓰건 모두 utf-8로 값이 전송됩니다. (이유는 묻지 마세요. 안찾아봤습니다.) 2번의 경우는 모든 경우에 euc-kr로 값이 전송되구요.

하지만 1번의 경우 분명 utf-8로 값이 전송되어야 할 것 같지만 Internet explorer는 euc-kr로 값을 전송합니다. 상식적으로도 이해가 가질 않지만 그렇게 동작하고 있습니다.

덕분에 utf-8로 값이 넘어왔다고 가정한 프로그램은 오동작을 하게 될 수 밖에 없습니다. 전 정말 Internet explorer를 이해할 수가 없습니다.

상식이 통하는 세상에 살고 싶습니다. Internet explorer 노력하세요.

'프로그램 > js' 카테고리의 다른 글

ajax와 인코딩문제  (0) 2015.03.27
javascript object 개념.  (0) 2015.03.27
jquery map  (0) 2015.03.27
slice()를 이용한 array copy  (0) 2015.03.27
jquery autocomplete  (0) 2015.02.22
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요

우선 .. 자바스크립트에 array 가 있을까 ?

정답은 없다 이다..

alert(typeof([])); 

를 실행하면 object를 출력한다.


아래는 자바스크립트의 간단한 기초(modern web 책을 참고하여 직접작성)



1.

객체 생성 방법.



//object 객체로 만들고 싶을때 

1)var foo = {};

2)var foo = new Object();



//사용자 정의 객체를 만들고 싶을때


1) 생성자함수(클래스)를 쓴다


ex)   function Student(name, korean, math, english, science){

this.이름 = name;

this.국어 = korean;

this.수학 = math;

this.영어 = english;

this.과학 = science;


//메서드

this.getSum = function(){

return this.국어+this.수학+this.영어+this.과학;

};

this.getAverage = function(){

return this.getSum()/4;

};

}


var student = new Student('윤하린',96,98,92,98).;


위와 같이 선언하여 사용한다.  그런데 이사용자 객체역시 object  객체의 상속을 받는 객체이다.

그런데 이와같이 클래스를 선언하게 되면 찍어낼때 마다 함수를 중복해서 찍어낸다.

그래서 자바스크립트는 프로토타입 공간을 만들었다. 프로토타입은 생성자 함수로 생성된 객체가 공통으로 가지는 공간이다. 

 function Student(name, korean, math, english, science){

this.이름 = name;

this.국어 = korean;

this.수학 = math;

this.영어 = english;

this.과학 = science;

}

이렇게 선언한뒤 prototype 객체를 이용하여 메소드를 추가한다.  ex) Student.prototype.func = function(){};

자바스크립트의 모든 함수는 prototype객체를 가진다. 


2.

그렇다면 javascript에서 기본 자료형과 객체의 차이점은 무엇일까?


자바스크립트에서 기본 자료형과 객체는 거의 차이점이 없다.

기본 자료형도 분명 존재하지만 var number = 23;

와 같이 선언하고 number. 와 같이 입력하면 기본자료형으로도 객체의 속성과 메서드를 사용할 수 있게 되며,

이 속성과 메서드를 사용하게 되는 순간 자동으로 객체로 변환된다. 


3.  

Object 객체란 무엇일까?


자바스크립트 최상위 객체이다 . 

위에서 설명한 생성방법으로 생성한다.

자바스크립트의 모든 기본 내장 객체는 Object 긱체를 기본으로 만들어진다.


4.

Array 객체란 ? 


여러가지 자료를 쉽게 관리할 수 있게 도와주는 객체이다 .


생성방법은 

var array1 = [52,44,22,...];

var array2 = new Array();


이렇게 생성한다.


ECMAScript5 Array 객체는 보다 특별한 함수를 가지는데 대표적인 함수로는..


forEach()가 있다. for in 반복문 보다 더 확장적으로 사용가능한 반복문이다. 

ex) array.forEach(function(element,index,array){

}); 


그런데 자바스크립트에는 연관배열이라는 것도 있다.

var array = new Array();


array["one"] = 2;

이런식으로 오름차순 숫자  인덱스가 아닌 문자를 인덱스로 사용하는 배열이다.


5. json 객체

   자바스크립트 객체의 형태를 가지는 문자열이다.


  JSON.stringfy()  --> 자바스크립트 객체를 JSON 문자열로 변환한다.

  JSON.parse() --> JSON문자열을 자바스크립트 객체로 변환한다. 


'프로그램 > js' 카테고리의 다른 글

ajax와 인코딩문제  (0) 2015.03.27
javascript object 개념.  (0) 2015.03.27
jquery map  (0) 2015.03.27
slice()를 이용한 array copy  (0) 2015.03.27
jquery autocomplete  (0) 2015.02.22
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요