1.라이브러리 설치(express,,jwt 등등)
2.환경변수 설정(env파일,config파일)
3.파일서버 작성(index.js 안에 쿠키 설정,cors설정,fs로 인증서 통신규약설정)
4.웹서버 만들기(controller 폴더안에서  로그인과 토큰에해당하는 인증과정 코드 작성하기)
+컴포넌트 작성
5.데이터베이스와 연결하는 models 파일 만들기


1.라이브러리 설치(express,,jwt 등등)
2.환경변수 설정(env파일,config파일)

DATABASE_PASSWORD=
DATABASE_USERNAME=root
DATABASE_NAME=authentication
ACCESS_SECRET=mini
REFRESH_SECRET=mini

env파일
const dotenv = require('dotenv');
dotenv.config();

module.exports = {
  development: {
    username: 'root',
    password: process.env.DATABASE_PASSWORD,
    database: 'authentication',
    host: '127.0.0.1',
    dialect: 'mysql',
    logging: false
  },
  test: {
    username: 'root',
    password: process.env.DATABASE_PASSWORD,
    database: 'authentication',
    host: '127.0.0.1',
    dialect: 'mysql',
  },
  production: {
    username: 'root',
    password: process.env.DATABASE_PASSWORD,
    database: 'authentication',
    host: '127.0.0.1',
    dialect: 'mysql',
  },
};
config 파일


3.파일서버 작성(index.js 안에 쿠키 설정,cors설정,fs로 인증서 통신규약설정)

onst express = require('express');
const cors = require('cors');
const session = require('express-session');
const logger = require('morgan');
const fs = require('fs');
const https = require('https');
const usersRouter = require('./routes/user');

const app = express();

const FILL_ME_IN = 'FILL_ME_IN';

const PORT = process.env.PORT || 4000;

// TODO: express-session 라이브러리를 이용해 쿠키 설정을 해줄 수 있습니다.
app.use(
  session({
    secret: '@codestates',
    resave: false,
    saveUninitialized: true,
    cookie: {
      domain: "localhost",
      path: '/',
      maxAge: 24 * 6 * 60 * 10000,
      sameSite: 'None',
      httpOnly: true,
      secure: true,
    },
  })
);
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

// TODO: CORS 설정이 필요합니다. 클라이언트가 어떤 origin인지에 따라 달리 설정할 수 있습니다.
// 메서드는 GET, POST, OPTIONS를 허용합니다.
const option = {
  origin: "http://localhost:3306",
  methods: "GET, POST, OPTIONS",
  credentials: true
};
app.use(cors(option));
/**
 * /users 요청에 대해서 라우터를 이용하기 때문에,
 * 반드시 아래와 같은 주소와 메서드로 요청을 보내야 합니다.
 *
 * POST https://localhost:4000/users/login,
 * POST https://localhost:4000/users/logout,
 * GET https://localhost:4000/users/userinfo
 */
app.use('/users', usersRouter);


let server;

// 인증서 파일들이 존재하는 경우에만 https 프로토콜을 사용하는 서버를 실행합니다.
// 만약 인증서 파일이 존재하지 않는경우, http 프로토콜을 사용하는 서버를 실행합니다.
// 파일 존재여부를 확인하는 폴더는 서버 폴더의 package.json이 위치한 곳입니다.
if (fs.existsSync("./key.pem") && fs.existsSync("./cert.pem")) {
  server = https
    .createServer(
      {
        key: fs.readFileSync(__dirname + `/` + 'key.pem', 'utf-8'),
        cert: fs.readFileSync(__dirname + `/` + 'cert.pem', 'utf-8'),
      },
      app
    )
    .listen(PORT);
} else {
  server = app.listen(PORT)
}
module.exports = server;
index.js파일


4.웹서버 만들기(controller 폴더안에서  로그인과 토큰에해당하는 인증과정 코드 작성하기)
+컴포넌트 작성

const { Users } = require('../../models');

module.exports = {
  post: async (req, res) => {
    // userInfo는 유저정보가 데이터베이스에 존재하고, 완벽히 일치하는 경우에만 데이터가 존재합니다.
    // 만약 userInfo가 NULL 혹은 빈 객체라면 전달받은 유저정보가 데이터베이스에 존재하는지 확인해 보세요
    const userInfo = await Users.findOne({
      where: { userId: req.body.userId, password: req.body.password },

    });
    if (!userInfo) {
      // your code here
      res.status(400).send({ data: null, message: "not authorized" });
    } else {
      // your code here
      // HINT: req.session을 사용하세요.
      req.session.sid = userInfo.userId;
      res.status(200).send({ data: userInfo, message: "ok" })
      console.log(req.session.sid)  // kimcoding
    }
  }
}
로그인 파일 예시 (서버파일에서 작성)
lass App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLogin: false,
      userData: null,
    };
    this.loginHandler = this.loginHandler.bind(this);
    this.logoutHandler = this.logoutHandler.bind(this);
    this.setUserInfo = this.setUserInfo.bind(this);
  }

  loginHandler() {
    this.setState({
      isLogin: true,
    });
  }

  setUserInfo(object) {
    this.setState({ userData: object });
  }

  logoutHandler() {
    this.setState({
      isLogin: false,
    });
  }

  render() {
    const { isLogin } = this.state;
    return (
      <div className='App'>
        {isLogin ? (
          <Mypage
            logoutHandler={this.logoutHandler}
            userData={this.state.userData}
          />
        ) : (
            <Login
              loginHandler={this.loginHandler}
              setUserInfo={this.setUserInfo}
            />
          )}
      </div>
    );
  }
}

export default App;
리액트파일 예시


5.데이터베이스와 연결하는 models 파일 만들기

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.js')[env];
const db = {};

let sequelize;
// 데이터베이스와 연결을 진행합니다.
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(
    config.database,
    config.username,
    config.password,
    config
  );
}
//models 폴더 내부에 존재하는 파일들을 읽어와 findOne, findAll과 같은 함수를 실행할수 있게끔 모델 인스턴스를 생성합니다.
fs.readdirSync(__dirname)
  .filter((file) => {
    return (
      file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js'
    );
  })
  .forEach((file) => {
    const model = require(path.join(__dirname, file))(
      sequelize,
      Sequelize.DataTypes
    );
    //db.users와 같이 db 객체 내부에 모델 인스턴스를 저장합니다.
    db[model.name] = model;
  });
//associate 부분에 내용이 존재한다면 자동으로 관계를 형성합니다.
Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;
//여러 모델 인스턴스가 담긴 객체를 내보냅니다.
module.exports = db;
model 파일 예시
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  /**
   * 해당 파일은 시퀄라이즈 ORM이 데이터베이스 쿼리를 진행하기 위해
   * 해당되는 테이블의 이름 및 어트리뷰트의 특성을 지정하는 파일입니다.
   * 또한 아래 associate 부분을 통해서 다른 테이블과의 관계를 작성할수 있습니다.
   * 
   * 이 파일은 서버가 실행되면 시퀄라이즈가 해당 내용을 바탕으로 findOne, findAll과 같은 함수를
   * 사용할수 있게끔 준비를 합니다.
   */
  class Users extends Model {

    static associate(models) {
    }
  }
  Users.init(
    {
      id: {
        type: DataTypes.NUMBER,
        primaryKey: true,
      },
      userId: DataTypes.STRING,
      password: DataTypes.STRING,
      email: DataTypes.STRING,
    },
    {
      sequelize,
      modelName: 'Users',
    }
  );
  return Users;

토큰인증과정서버를 만드는과정을 처음부터만든다면 이라는 고민으로 시작해 구축순서를 만들어보았습니다.

OAUTH 는 콜백함수에서 토큰을 불러오고

require('dotenv').config();

const clientID = process.env.GITHUB_CLIENT_ID;
const clientSecret = process.env.GITHUB_CLIENT_SECRET;
const axios = require('axios');

module.exports = async (req, res) => {
  // req의 body로 authorization code가 들어옵니다. console.log를 통해 서버의 터미널창에서 확인해보세요!
  console.log(req.body);
  axios.post('https://github.com/login/oauth/access_token',{
     client_id: clientID,
     client_secret : clientSecret,
     code: req.body.authorizationCode
  },
 {headers: {accept: 'application/json'}}).then(data =>{
    res.status(200).send({ accessToken: data.data.access_token})
  })
  .catch(err => {console.log(err)})
  callback

index에서 사용하는식으로 서버를 구축하면 끝남!

const express = require('express');
const app = express();
const cors = require('cors');
const PORT = process.env.PORT || 8080;

const handleCallback = require('./controller/callback')
const handleImages = require('./controller/images')

app.use(express.json());

app.use(
  cors({ origin: true })
);

app.post('/callback', handleCallback);

app.get('/images', handleImages)

app.listen(PORT, () => {
  console.log(`listening on port ${PORT}`);
});

module.exports = app;
index

사실 처음 프로젝트를 시작할떄는

디자인을 그리고 서버를 구축하는거라고 생각하는데 프론트엔드와 백엔드가 동시에 일을한다고 생각한다면

환경변수와 파일서버구축,웹서버만들기와, 데이터베이스 연결을 담당하는 모델파일만들기->>백엔드

컴포넌트제작,api엮기->>프론트엔드라고 나뉜다고 생각합니다.

 

복사했습니다!