웹 어플리케이션 보안 2016년 2학기 4. Restful node apI 만들기
4. RESTful Node API 만들기 Chap 9. Build a RESTful Node API
RESTful Web services REST = REpresentational State Transfer REST 라는 용어는 2000년 로이필딩(Roy Fielding) 박사의 논문에 서 처음 소개 분산 하이퍼미디어 시스템을 위한 www 같은 소프트웨어 아키텍 처의 한 형식. ROA(Resource Oriented Architecture)를 따르는 웹 서비스 아키텍처 URI와 HTTP 메소드를 이용해 객체화된 서비스에 접근하는 것. Interconnectivity - 여러 개의 디바이스, 여러 웹사이트들과의 연 결성을 쉽게 제공 Open API - third-party application에 서비스 접근 허용
RESTful Web services URI를 이용한 자원의 식별 HTTP method RESTful web service 모든 자원(Resource)는 HTTP URL에 의해서 표현 https://www.facebook.com/groups/jbuis/ HTTP method 해당 자원에 대한 행동은 HTTP Method를 사용하여 표현 GET, POST, PUT, DELETE RESTful web service
REST Examples – IFTTT https://ifttt.com/
REST Examples - Twitter API
REST Examples – Facebook graph API
이번 장에서 할 일 CRM tool 제작 다음을 이용하여 RESTful API를 생성하기 생성한 API 테스트하기 Customer Relations Management (사용자 관리 툴) 다음을 이용하여 RESTful API를 생성하기 Node Express 4 Express Router Mongoose (MongoDB와의 연동) 생성한 API 테스트하기 Postman (in Chrome) 이용 RESTClient (in Firefox) 이용
CRM tool 제작 생성할 API의 기능 Handle CRUD for an item (users) Create, Read, Update, Delete 기능 Have a standard URL http://example.com/api/users http://example.com/api/users/:user_id GET, POST, PUT, DELETE 등의 메서드 이용 Use the proper HTTP verbs to make it RESTful JSON 형식의 데이터 리턴 모든 요청을 서버 콘솔에 로깅
CRM tool 제작 파일 구조 새로운 프로젝트 폴더 생성 md node-api cd node-api npm init
CRM tool 제작 관련 패키지 설치 생성된 package.json 파일 npm install express morgan mongoose body-parser bcrypt-nodejs --save
CRM tool 제작 설치된 패키지들의 역할 express – Node 웹 프레임워크 morgan – 모든 request들을 서버 console에 로그 남김 mongoose – MongoDB database와의 연동 body-parser – 사용자의 POST 컨텐츠를 가져와서 해석하는 기능 bcrypt-nodejs – 패스워드를 해쉬하여 데이터베이스에 저장
Server.js 파일 작성 // Filename: server.js // BASE SETUP // ====================================== // CALL THE PACKAGES -------------------- var express = require('express'); // call express var app = express(); // define our app using express var bodyParser = require('body-parser'); // get body-parser var morgan = require('morgan'); // used to see requests var mongoose = require('mongoose'); // for working w/ our database var port = process.env.PORT || 8080; // set the port for our app // APP CONFIGURATION --------------------- // use body parser so we can grab information from POST requests app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); // configure our app to handle CORS requests (CORS=Cross-Origin Resource Sharing) app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type, Authorization'); next(); }); // log all requests to the console app.use(morgan('dev'));
Server.js 파일 작성 // ROUTES FOR OUR API // ============================= // basic route for the home page app.get('/', function(req, res) { res.send('Welcome to the home page!'); }); // get an instance of the express router var apiRouter = express.Router(); // test route to make sure everything is working // accessed at GET http://localhost:8080/api apiRouter.get('/', function(req, res) { res.json({ message: 'hooray! welcome to our api!' }); // more routes for our API will happen here // REGISTER OUR ROUTES ------------------------------- // all of our routes will be prefixed with /api app.use('/api', apiRouter); // START THE SERVER // =============================== app.listen(port); console.log('Magic happens on port ' + port);
서버 실행 및 테스트 서버 실행 브라우저로 확인 nodemon server.js
Postman으로 API 테스트 크롬 브라우저에 Postman 확장프로그램 설치
Postman으로 API 테스트 URL에 http://localhost:8080/api 를 입력하고 GET을 선 택하여 전송
데이터베이스에 연결하기 MongoDB에 연결 Server.js 에 mongoose.connect( ) 구문 추가 // configure our app to handle CORS requests app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, \ Authorization'); next(); }); // log all requests to the console app.use(morgan('dev')); mongoose.connect('mongodb://localhost:27017/myDatabase');
참고 - Modulus.io 이용하기 회원가입 https://modulus.io/ https://my.modulus.io/register
참고 - Modulus.io 이용하기 데이터베이스 생성 주소를 복사하여 이용 mongodb://<user>:<pass>@jello.modulusmongo.net:27017/eryter7A mongoose.connect('mongodb://sultan:sultan@jello.modulusmongo.net:27017/eryter7A');
사용자 모델 생성 User Model 생성 (app/models/user.js) app/models 폴더 생성 스키마 생성 name, username, password 준비 username에 unique index를 생성 select: false 사용자 검색시 패스워드는 제공하지 않음 pre 함수는 사용자의 패스워드 입력을 해쉬값 계산하여 패스워드로 저장하는 save() 함수를 생성 User Model 생성 (app/models/user.js) app/models 폴더 생성 user.js 생성
사용자 모델 생성 (app/models/user.js) 함수 bcrypt.hash는 사용자의 패스워드입력 user.password을 입력값으로 하는 비동기 함수로 성공하면 hash를, 실패하면 err를 리턴 함수 bcrypt.comparePassword는 사용자의 패스워드 입력값 password와 DB에 저장된 정보인 user.password 비교하여 같으면 true, 틀리면 false를 리턴 생성된 모델을 User라는 이름으로 export
Mongoose 미들웨어 pre http://mongoosejs.com/docs/middleware.html
Bcrypt-nodejs hash 함수 https://www.npmjs.com/package/bcrypt-nodejs 동기식 활용 비동기식 활용
메인 서버에서 user 모델을 연결 server.js 파일에서 user 모델을 읽어옴 // CALL THE PACKAGES -------------------- var express = require('express'); // call express var app = express(); // define our app using express var bodyParser = require('body-parser'); // get body-parser var morgan = require('morgan'); // used to see requests var mongoose = require('mongoose'); // for working w/ our database var User = require('./app/models/user'); var port = process.env.PORT || 8080; // set the port for our app
Express 라우터 연결 API 및 라우터 연결 계획
로깅을 위한 미들웨어 수정 모든 request들에 대해 콘솔에 로그를 남기도록 미들웨 어를 수정 (server.js 파일) // get an instance of the express router var apiRouter = express.Router(); // middleware to use for all requests apiRouter.use(function(req, res, next) { // do logging console.log('Somebody just came to our app!'); // we'll add more to the middleware in Chapter 10 // this is where we will authenticate users next(); // make sure we go to the next routes and don't stop here }); // test route to make sure everything is working // accessed at GET http://localhost:8080/api apiRouter.get('/', function(req, res) { res.json({ message: 'hooray! welcome to our api!' }); // more routes for our API will happen here // REGISTER OUR ROUTES ------------------------------- // all of our routes will be prefixed with /api app.use('/api', apiRouter);
Creating a User POST (/api/users) apiRouter.route('/users')에 .POST 추가
Getting All Users (GET /api/users) apiRouter.route('/users')에 .GET 추가
Postman으로 사용자 생성 테스트 주소- http://localhost:8080/api/users Method- POST Body / x-www-form-urlencoded 를 선택하고 Key: value 값 입력 name: username: password: Send 버튼 사용자 생성 완료 {“message” : “User created!”}
Postman으로 사용자 생성
생성된 사용자 확인
사용자 생성시 에러 이미 존재하는 username으로 사용자 생성시 에러 발생
Getting All Users (GET /api/users) apiRouter.route('/users')에 .GET 추가 전체 사용자 목록 읽어오기
전체 사용자 목록 얻기 GET - http://localhost:8080/api/users
Creating Routes for A Single Item User_id를 파라메터로 갖는 한 유저를 위한 라우팅 특정 사용자 정보 읽어오기 특정 사용자 정보 업데이트하기 특정 사용자 삭제하기
Creating Routes for A Single Item 한 사용자 정보 얻기 Getting a Single User (GET /api/users/:user_id)
Creating Routes for A Single Item 한 사용자 정보 얻기
Creating Routes for A Single Item 한 사용자 정보 업데이트하기 Updating a User’s Info (PUT /api/users/:user_id)
Creating Routes for A Single Item 사용자 이름을 Chris에서 Chris Lee로 변경
Creating Routes for A Single Item 사용자 정보 삭제하기 Deleting a User (DELETE /api/users/:user_id)
Creating Routes for A Single Item Chris Lee 사용자를 삭제
전체 코드 참조 https://github.com/scotch-io/mean-machine-code/blob/master/09-node-api/server.js 참조 https://github.com/scotch-io/mean-machine-code <=== 전체 코드
결론 Node와 express에서 CRUD를 다루는 방법을 배움 Create, read, update, delete Node에서 API를 만드는 방법을 배움. 이런 방법으로 더 많은 일을 할 수 있음 인증 추가 에러메시지 처리 추가 사용자 정보 처리 이외 다른 작업