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엮기->>프론트엔드라고 나뉜다고 생각합니다.
'서버관련' 카테고리의 다른 글
브라우저캐시 심화(?) (0) | 2022.04.26 |
---|---|
HTTP와 IP 그리고 [TCP,UDP]의 원리 및 차이점, QUID 짤막 (0) | 2022.04.26 |
앱서버와 웹서버의 차이점 (0) | 2022.04.07 |
지정된 Origin의 중요성과 사전요청/Content-type에 대해(CORS도있음) (0) | 2022.04.06 |
REST API (0) | 2022.03.31 |