June 24th 2019
Contents
Make Authentication server
웹 애플리케이션의 로그인 절차를 잘 구현하고, 보안 및 UX를 증진시키기 위해서는 User Authentication에 대해 이해하는 것이 중요합니다.
위의 방식으로 진행 시 유저가 인증 정보를(이메일, 비밀번호) 제공하면, 서버로부터 JWT를 전달받습니다. 그러면, 클라이언트는 매 요청마다 어떠한 방식으로 JWT를 포함해 인증된 요청임증 증명할 수 있을까요? 우리는 Cookie를 통해 이 인증 조각을 전달할 수 있고, 또는 직접 Token을 설정할 수도 있습니다.
HTTP Protocol은 Connectionless, Stateless라는 특징이 있는데, 이러한 특징이 가져오는 결과 중 하나는 서버에서 사용자를 식별할 수 없다는 점입니다. 이러한 Stateless한 환경에서 어떠한 세션 관리(session management), 사용자 맞춤(Personalization), 트래킹(Tracking) 같은 작업을 원할 때 Cookie와 Session을 사용할 수 있습니다.
Cookie의 경우 어떠한 요청을 보낼 시 브라우저에서 자동으로 포함해 줍니다. Cookie는 해당하는 도메인에만 포함되고 사용할 수 있고, 다른 도메인으로는 발송할 수 없습니다. 반면, Token은 도메인이 달라고 Header에 설정해 발송할 수 있습니다. 현재는 Token에 기반한 방식이 많이 사용되며, 이 방식이 웹 확장에도 더 좋습니다.
Node.js 및 Express를 통해 email, password 방식의 authentication server를 구축해 보도록 하겠습니다.
controllers
| |__authentication.js
models
| |__user.js
services
| |__passport.js
|_index.js
|_router.js
index.tsx 파일은 server app이 시작하는 root 파일로 server와 express, database를 설정합니다. 서버로 들어오는 요청 확인을 위해 morgan middleware도 추가 했습니다.
// Main starting point of the application
const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const app = express();
const router = require('./router');
const mongoose = require('mongoose');
const cors = require('cors');
// DB Setup
mongoose.connect('mongodb://localhost/auth');
// App setup
app.use(morgan('combined'));
app.use(cors());
app.use(express.json());
router(app);
// Server setup
const port = process.env.PORT || 3100;
const server = http.createServer(app);
server.listen(port);
console.log('Server listening on:', port);
로그인 진행 시 Database의 User model에는 email, password 속성이 필요합니다. 두 속성 모두 type은 String이며, 이메일은 중복이 없어야 하고 대소문자 구분이 없어야 하기 때문에 아래와 같이 lowercase를 지정하여 userSchema를 생성합니다. 생성한 schema를 이용해 mongoose model을 만들고 export 합니다.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Define our model
const userSchema = new Schema({
email: { type: String, unique: true, lowercase: true },
password: String
});
// Create the model class
const ModelClass = mongoose.model('user', userSchema);
// Export the model
module.exports = ModelClass;
이후에 비밀번호를 암호화하고, 비교하는 작업이 추가해야 하며, 해당 내용에 대해서는 이 글 후반부에 다시 살펴보도록 하겠습니다.