1. 카카오 개발자 페이지에 접속후, 로그인한다.

https://developers.kakao.com/

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

2. 새 앱을 하나 생성한다.(기존 앱으로 해도 되고...)

내 애플리케이션 메뉴 -> + 애플리케이션 추가하기 선택..

 

3. 플랫폼 -> Web 플랫폼 등록

localhost로 할꺼니까.. 포트와 함께 적어준다. 나같은 경우,  http://localhost:4000/로 접속할 것이다.

4. 저장하면, 카카오 로그인을 사용하기 위해서는 Redirect URI를 등록해야 한다고 나온다. 옆에 등록하러 가기를 눌러 이동한다.

5. 하단에 Redirect URI 등록 버튼을 눌러 등록한다. 그리고  원하는 URI를 적어준 뒤 저장한다.

http://localhost:4000/auth/kakao/callback 

이런식으로 ...

만약, 잘못 입력하거나 입력하지 않았을 경우 다음과 같은 에러가 발생한다.

아...카카오는 에러페이지도 귀엽네...

어쨋든... 해결방안을 눌러보면, 에러코드들이 줄줄이 명시되어있다.

그 중에서, 검색을 해보면... 자세한 에러에 대한 설명과 함께 해결 방안까지 한국어로 되어있으니 얼마나 편한가! 

 

6. 위에 활성화 설정 -> 상태를 OFF에서 ON으로 바꿔준다. 

7. 동의항목을 설정해줘야, 유저로부터 동의를 얻어 정보를 가져올 수 있다. 

Posted by sungho88
,

4000번 포트를 사용하고 있기 때문에 발생하는 에러이다.

4000번 포트를 사용하고 있던 서버를 종료했음에도 불구하고, 살아있기 때문에 발생하는 것이다.

이럴 경우,

kill을 해서 포트를 꺼버리던지, 다른 포트 예를 들면 4444를 쓰던지 해야한다.

 

그럼 어떻게 포트 프로세스를 중단시킬까?

 

1. 4000포트를 사용중인 프로세스 찾기 

$ lsof -i :4000

 

하면, 다음과 같이 사용중인 녀석이 나온다. 이제 이 것을 죽여버리자!

COMMAND   PID        USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node    13888         jsh   28u  IPv6 0x75b989f13d6c5017      0t0  TCP *:terabase (LISTEN)

 

2. 죽이기

 

kill -9 13888

 

즉, kill -9 PID을 하면, 해당 프로세스가 종료된다.  -9는 알바벳 쥐(g)가 아니라 숫자 구(9) !! 주의하자! 처음엔 나도 -g로 썼었다;;

 

그러면, 위 에러가 나던데에서 4000번 포트를 사용할 수 있게 된다.

Posted by sungho88
,

데이터를 저장하는 방식은 몇 가지가 존재합니다.

초기에는 파일(File)에 저장하여 사용했습니다. 하지만, 문제가 많았습니다.

보안적인 문제도 있었고, 검색이나 정렬등을 하기에 한계가 있었습니다. 그래서 등장합니다~~

 

바로바아~~~로~~~~~~ Database !!

 

이 방식은 우리 컴퓨터에 깔려있는 스프레드 시트 또는 엑셀과 비슷한 구조로 되어있다는 것을 알 수 있습니다.

공통점으로는 표의 형태로 눈에 보기 쉽게 되어있으며, 정렬하기 쉽고 숨기거나 검색을 하기도 용이합니다.

하지만, 엑셀도 결국 파일이므로 데이터를 내 컴퓨터에서만 사용할 수 있습니다.

하지만, 데이터베이스는 서버 기반으로 코드를 통해서 데이터를 관리할 수 있으며, 전 세계 사람 누구나 볼 수 있도록 할 수 있습니다.

 

데이터베이스는 RDBMS(관계형 데이터베이스 시스템)인 SQL형과 No-SQL형 두 가지 종류로 나뉩니다.

 

Structured Query Language

 

이 두가지는 나중에 알아보고 어떤것이 가장 인기있는 데이터베이스인지 알아봅시다.

 

https://db-engines.com/en/ranking

이렇답니다. 오라클이라는 초대형 데이터베이스와 견주어도 스코어가 막상막하인것 보이시나요?

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

MySQL 용어

id name age
1 GIL 50
2 JANG 32

이러한 구조로 데이터가 저장되게 되는데, 이 표를 Table이라고 하며, Table들이 하나의 Database로 저장되어 관리됩니다.

Mysql에서는 스키마(schema)라는 의미와 데이터베이스를 같은 뜻으로 취급한다. 따라서, 코딩도 동일합니다.

데이터베이스마다 스키마의 의미가 다르기 때문에 난해한 용어인 것 같습니다. 어쨋든 Mysql에서는 테이블 등의 오브젝트 집합입니다.

 

mysql > CREATE DATABASE `user`;

mysql > CREATE SCHEMA `post`;

 

그럼, mysql를 사용해봅시다.

 

터미널을 열고, 다음과 같이 root로 접속해봅시다.

 

$ mysql -u root -p

 

Mysql을 설치할때 입력했던 비밀번호를 넣어주면, 

이렇게 Welcome!!!

 

mysql> 

 

이렇게 나오면, mysql에 접속이 성공적으로 마쳤습니다! 예~ 이제 Mysql문법을 하나하나 작성해봅시다.

 

1. 데이터베이스 생성 --> create database 데이터베이스이름; ( CREATE DATABASE 데이터베이스이름;)

 

대소문자는 구분없이 명령은 잘 되는데, 대문자로 하는게 관습이라고 합니다.

 

무조건 문장의 끝은 세미콜론(;)을 붙여줘야합니다. 그렇지 않고 Enter를 치면 안 끝났다고 생각하고 아래와 같이 계속 말하라고 합니다.

문장 끝에 ;을 입력해주세요

 

에러 없이 데이터베이스 생성!

 

무조건 Query OK, 가 나와야 성공한 겁니다. 그외 이상한 문장이 나왔으면 오타일 확률 99.999%입니다~~ 오타 주의!!

에러 문장

 

2. 데이터베이스 제거(삭제) --> drop database 데이터베이스이름;

 

3. 데이터베이스 목록 보기

show databases;

 

4. 특정(데이터베이스이름) 데이터베이스 선택하기(사용하겠다)

user 데이터베이스이름;

 

5. 테이블 생성하기 create table 테이블명(....ㅇㅇ...);

 

 

 

6. 테이블 목록 보기

show tables;

 

6. 테이블 삭제하기

show table 테이블명;

 

테이블 이름 바꾸기

rename table 기존_테이블명 to 변경할_테이블명;

 

8. 테이블 구조 확인하기

DESC users;

 

CRUD 명령어 작성

 

1. 생성하기. Create가 아니라, insert 명령어입니다.

 

1. INSERT INTO테이블이름(필드이름1, 필드이름2, 필드이름3, ...)  VALUES (데이터값1, 데이터값2, 데이터값3, ...)

 

2. 조회하기 : Select

 

SELECT * FROM users; -- users 테이블에 있는 모든 row를 보여준다. 

SELECT id, email FROM users; -- users 테이블에 있는 모든 row를 보여주는데, id와 email만 보여준다.

SELECT id, email FROM users WHERE first_name="HONG"; -- users 테이블에 있는 row중에, first_name이 HONG인 사람만 보여주는 조건식이다.


WHERE 문 뒤에 ORDER BY로 정렬까지 붙여서 사용할 수 이싿 

Posted by sungho88
,

시퀄라이즈는 SQL문을 자바스크립트 프로젝트 내에서 자바스크립트 객체로 작성할 수 있습니다. 

그렇지만, 시퀄라이즈 자체의 SQL과 다른 문법이 존재하기 때문에 이것도 익히는데 시간이 걸릴 것 같습니다.

또한, SQL문 데이터베이스를 다룰 백엔드 개발자라면 필수로 배우고 알아둬야하기 때문에 어떤 것을 쓰는게 맞을지 모르겠습니다.

하여튼 Sequelize 문법을 알아보겠습니다. 위에 SQL을 적어 해당 SQL문이 시퀄라이즈로 작성할때 어떻게 바뀌는지 보겠습니다.

 

먼저, 가장 간단한 CRUD부터 익혀보겠습니다. 

 

1) 생성하기(INSERT) 

INSERT INTO users (name,age,married,comment) VALUES ('JANG', 24, 0, '코멘트~');

 

User.create({ // Promise 방식 

name: 'JANG',

age:24,

married: false,

comment: '코멘트~'

});

 

2) 조회하기(SELECT)

// 모든 컬럼을 전부 가지고 오기.

SELECT * FROM users;

 

User.findAll():

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

// 일부 컬럼만 전부 가지고 오기.

SELECT name, married FROM users;

 

User.findAll({

attributes: ['name','married'],

});

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

[WHERE절 추가]

 

SELECT * FROM users WHERE authorId = 2

 

User.findAll({

 where: { authorId: 2 }

});  

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

SELECT * FROM users WHERE authorId = 12 AND status = 'active';

 

User.findAll({

 where: {

  authorId: 12,

  status: 'active'

   }

});

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

Op라는 연산자가 존재한다. 이것으로 조건문등의 조건을 정할 수 있다.

 

Op.eq --> SELECT * FROM users WHERE authorId = 2와 동일하다.

const { Op } = require("sequelize");
User.findAll({
  where: {
    authorId: {
      [Op.eq]: 2
    }
  }
});

Op.and --> 위 SELECT * FROM users WHERE authorId = 12 AND status = 'active'; 와 동일해짐.

const { Op } = require("sequelize");
User.findAll({
  where: {
    [Op.and]: [
      { authorId: 12 },
      { status: 'active' }
    ]
  }
});

Op.or --> SELECT * FROM users WHERE authorId = 12 OR authorId = 13; 을 표현할 수 있다.

const { Op } = require("sequelize");
User.findAll({
  where: {
    [Op.or]: [
      { authorId: 12 },
      { authorId: 13 }
    ]
  }
});

위와 같이 동일한 필드를 조건문으로 찾을 경우, 구조를 바꿔서 좀 더 읽기 쉽게 바꿀 수 있다.

 

DELETE FROM post WHERE authorId = 12 OR authorId = 13;

const { Op } = require("sequelize");
Post.destroy({
  where: {
    authorId: {
      [Op.or]: [12, 13]
    }
  }
});

그 외 엄청나게 많은 종류의 연산자를 제공한다.

너무 많고해서 복붙해 넣었다. 이런게 있구나만 보고 넘어가자.

const { Op } = require("sequelize");
User.findAll({
  where: {
    [Op.and]: [{ a: 5 }, { b: 6 }],            // (a = 5) AND (b = 6)
    [Op.or]: [{ a: 5 }, { b: 6 }],             // (a = 5) OR (b = 6)
    someAttribute: {
      // Basics
      [Op.eq]: 3,                              // = 3
      [Op.ne]: 20,                             // != 20
      [Op.is]: null,                           // IS NULL
      [Op.not]: true,                          // IS NOT TRUE
      [Op.or]: [5, 6],                         // (someAttribute = 5) OR (someAttribute = 6)

      // Using dialect specific column identifiers (PG in the following example):
      [Op.col]: 'user.organization_id',        // = "user"."organization_id"

      // Number comparisons
      [Op.gt]: 6,                              // > 6
      [Op.gte]: 6,                             // >= 6
      [Op.lt]: 10,                             // < 10
      [Op.lte]: 10,                            // <= 10
      [Op.between]: [6, 10],                   // BETWEEN 6 AND 10
      [Op.notBetween]: [11, 15],               // NOT BETWEEN 11 AND 15

      // Other operators

      [Op.all]: sequelize.literal('SELECT 1'), // > ALL (SELECT 1)

      [Op.in]: [1, 2],                         // IN [1, 2]
      [Op.notIn]: [1, 2],                      // NOT IN [1, 2]

      [Op.like]: '%hat',                       // LIKE '%hat'
      [Op.notLike]: '%hat',                    // NOT LIKE '%hat'
      [Op.startsWith]: 'hat',                  // LIKE 'hat%'
      [Op.endsWith]: 'hat',                    // LIKE '%hat'
      [Op.substring]: 'hat',                   // LIKE '%hat%'
      [Op.iLike]: '%hat',                      // ILIKE '%hat' (case insensitive) (PG only)
      [Op.notILike]: '%hat',                   // NOT ILIKE '%hat'  (PG only)
      [Op.regexp]: '^[h|a|t]',                 // REGEXP/~ '^[h|a|t]' (MySQL/PG only)
      [Op.notRegexp]: '^[h|a|t]',              // NOT REGEXP/!~ '^[h|a|t]' (MySQL/PG only)
      [Op.iRegexp]: '^[h|a|t]',                // ~* '^[h|a|t]' (PG only)
      [Op.notIRegexp]: '^[h|a|t]',             // !~* '^[h|a|t]' (PG only)

      [Op.any]: [2, 3],                        // ANY ARRAY[2, 3]::INTEGER (PG only)

      // In Postgres, Op.like/Op.iLike/Op.notLike can be combined to Op.any:
      [Op.like]: { [Op.any]: ['cat', 'hat'] }  // LIKE ANY ARRAY['cat', 'hat']

      // There are more postgres-only range operators, see below
    }
  }
});

 

Posted by sungho88
,

Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more.

 

라고 공식 홈페이지 첫 화면에 나와있습니다... 영알못인 저는 구글 번역기에 넣어보겠습니다.

 

Sequelize는 Postgres, MySQL, MariaDB, SQLite 및 Microsoft SQL Server를위한 Promise 기반 Node.js ORM입니다.

견고한 트랜잭션 지원, 관계, eager 및 lazy로드, 읽기 복제 등을 제공합니다.

 

ORM = Object Relational Mappings

 

뭔 말인지 모르겠지만, 쉽게 말해 Sequelize는 Node.js에서 DB 서버를 생성할 수 있도록 해주는 것 같습니다.

 

Sequelize 설치

 

npm 또는 yarn을 이용해서 설치할 수 있습니다.

 

npm install sequelize (yarn add sequelize)

 

database 연결하기

 

const { Sequelize } = require('sequelize');

const sequelize = new Sequelize('database', 'username', 'password', etc_config);

 

[Sequelize 특징]

Sequelize에서 제공하는 대부분의 메서드는 비동기식이므로 Promise를 반환합니다.

그러므로, Promise API (예 : then, catch, finally 사용)를 즉시 사용할 수 있습니다.

Posted by sungho88
,

router.get('/', (req,res,next)=> {

try {

const user = await User.findOne({

...

});

res.render('login', {

user

})

} catch (error) {

console.error(error);

next(error);

}

})

 

이와 같은 데이터베이스에 접속하는 코드를 실행하였는데, 에러가 발생했다.

너무나 많이 발생하는 에러라 이젠 외워지기 시작했다.

이참에 블로그에 정리해두려고 글을 작성한다.

 

이것은 await를 사용하기 위해서는 async를 반드시 함수 앞에 붙여줘야 한다. 바늘과 실처럼...

 

router.get('/', async (req,res,next)=> {

try {

const user = await User.findOne({

...

});

res.render('login', {

user

})

} catch (error) {

console.error(error);

next(error);

}

})

Posted by sungho88
,

app.js에서 라우터를 사용하는데, 이러한 에러가 발생했다.

 

 

const pageRouter = require("./routes/page");  

 

app.use("/", pageRouter);

 

이렇게 단순한 두 줄에서 에러가 났다. 

 

처음에는 오타인 줄 알고 유심히 봤지만 너무 단순한 문장이라 에러날 곳이 없었다.

 

검색했다. 문제는 page.js 파일 안에 있었다.

 

바로~ router를 모듈로 export해주지 않아서 난 에러였다. 이런이런~

 

module.exports를 통해서 router를 등록해줘야 다른 모듈에서 사용이 가능하기 때문에 꼭 붙여줘야한다.

 

참고로 꼭 맨 밑에 작성하지는 않아도 된다. 하지만 꼭 있어야한다.

 

이번 에러로 하나 배웠다. 실수하지 말고 module.exports는 잊지말자!! 

 

 

 

Posted by sungho88
,

원격 서버에 있는 데이터베이스에 들어있는 데이터를 추출하여,

 

개인 pc에서 테스트를 하고 싶었다. 그래서, 일단 빼는 방법을 찾게 되었다.

 

mysql에서 데이터 뽑기

 

.cvs 파일로 뽑으면 된다. 다만, 구분자는 쉼표(,)로 하면 오류가 발생한다.

 

왜냐하면 게시판 데이터이기 때문에, 에디터 코드가 들어가 있거나, 장문의 글들이 있기 때문에

 

쉼표는 데이터를 구분해줄 수 없기 때문이다. 따라서 탭으로 구분하는 것이 좋다

 

이 것은 ','로 끊으라는 것인데, 이렇게하면 원하지 않는 결과가 나온다.

 

이렇게 하면, 탭으로 구분하라는 것이다. 이렇게 하면

 

쿼리 오케이 하면? 성공이다!

위치는 /tmp/mydaya.csv로 해놨으니 찾아가보면 엑셀 모양으로 저장이 되어있는 것을 볼 수 있다.

 

이것을 가져오는데... 문제가 발생한다.

 

한글이 깨진 것이다.

 

메모장에서 열면? 잘 나온다... 그렇다면 굳이 .csv 확장자를 할 필요가 없었다.   .txt로 

텍스트 파일로 받아도 괜찮다. 한글도 안 깨지고...아래와 같이 하는게 더 시간 단축이 될 것이다. 

 

mysql에서 데이터 넣기

1. phpmyadmin

2. 터미널에서 텍스트로 LOAD FILE

3. Mysql workbench

 

등으로 할 수 있는데,

 

phpmyadmin으로 했다.

 

<-- 가져오기 -- 파일선택 -- utf-8 -- 형식 : CSV --> 

 

열(컬럼) 구분자를 \t로 맞춰줘야한다.

 

 

 

Posted by sungho88
,

routes.js라는 파일에 라우터를 정의해두고, 


app.js에서  import routes from './routes.js'로 사용했다


그런데 다음과 같은 에러가 발생했다.


typeerror: router.use() requires a middleware function but got a object


음 ..


router.use()는 미들웨어 기능이 필요하지만(요구되지만) Object가 있습니다?


뭔 말인가 찾아보다가..


export defalut routes;


가 없는 것을 발견했다. 이런;


추가해줬더니 에러 해결!


이런!






로 라우터를 

Posted by sungho88
,

백엔드의 원리 & 필요성

1. 벡엔드는 언제 필요할까?

벡엔드는 필수는 아니며, 필요에 따라 선택한다.

단순히 보여주기 위한 웹사이트를 만든다면, 벡엔드가 필요없다.

HTML과 CSS 자바스크립트, JQuery 등으로 만들수 있다.

하지만, 뭔가를 저장하고자 하는 것이 존재한다면, 벡엔드를 필요로 한다.

사용자의 회원가입이나 게시판에서의 업로드, 또는 채팅 기능을 제공하고자 한다면, 벡엔드가 필요하다.


[Django] 

발음 : 디장고 No. 장고 Good

장고는 프레임워크이다. 

프로그래밍 언어가 아니다.

개발 속도가 매우 빠르다.

많은 작업을 짧은 시간에 할 수 있다.

안전하다.

편리하다.

1. 프레임워크와 라이브러리 차이점

라이브러리는 도구(Tool)이며 직접 불러서 작업을 수행하기 위해 사용. ( JQuery, React ...) 

프레임워크는 방식. 코드가 실행되는 방식.

2. Django의 장점



Posted by sungho88
,