Toggle navigation
Toggle navigation
This project
Loading...
Sign in
박민정
/
We-Shop
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
박민정
2021-06-06 23:12:06 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
1fb939e703f74f57db599392396f21a380858342
1fb939e7
1 parent
ed0b13aa
[fix] Fix the error
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
175 additions
and
177 deletions
We-Shop/package-lock.json
We-Shop/package.json
We-Shop/server/index.js
We-Shop/server/middleware/auth.js
We-Shop/server/models/User.js
We-Shop/server/routes/users.js
We-Shop/package-lock.json
View file @
1fb939e
This diff could not be displayed because it is too large.
We-Shop/package.json
View file @
1fb939e
{
"name"
:
"boiler-plate"
,
"name"
:
"
react-
boiler-plate"
,
"version"
:
"1.0.0"
,
"description"
:
""
,
"description"
:
"
react boiler plate
"
,
"main"
:
"index.js"
,
"engine"
:
{
"node"
:
"10.16.0"
,
"npm"
:
"6.9.0"
},
"scripts"
:
{
"start"
:
"node server/index.js"
,
"backend"
:
"nodemon server/index.js"
,
"
test"
:
"echo
\"
Error: no test specified
\"
&& exit 1
"
,
"dev"
:
"concurrently
\"
npm run backend
\"
\"
npm run start --prefix client
\"
"
"
frontend"
:
"npm run start --prefix client
"
,
"dev"
:
"concurrently
\"
npm run backend
\"
\"
npm run start --prefix client
\"
"
},
"author"
:
"
mindyeoi
"
,
"author"
:
"
John ahn
"
,
"license"
:
"ISC"
,
"dependencies"
:
{
"bcrypt"
:
"^5.0.1"
,
"body-parser"
:
"^1.19.0"
,
"concurrently"
:
"^6.2.0"
,
"cookie-parser"
:
"^1.4.5"
,
"bcrypt"
:
"^3.0.6"
,
"body-parser"
:
"^1.18.3"
,
"cookie-parser"
:
"^1.4.3"
,
"cors"
:
"^2.8.5"
,
"debug"
:
"^4.1.1"
,
"express"
:
"^4.17.1"
,
"jsonwebtoken"
:
"^8.5.1"
,
"mongoose"
:
"^5.12.12"
"moment"
:
"^2.24.0"
,
"mongoose"
:
"^5.4.20"
,
"react-redux"
:
"^5.0.7"
,
"saslprep"
:
"^1.0.3"
,
"supports-color"
:
"^7.1.0"
},
"devDependencies"
:
{
"nodemon"
:
"^2.0.7"
"concurrently"
:
"^4.1.0"
,
"nodemon"
:
"^1.19.1"
}
}
...
...
We-Shop/server/index.js
View file @
1fb939e
const
express
=
require
(
'express'
)
const
express
=
require
(
"express"
)
const
app
=
express
()
const
port
=
5000
const
port
=
process
.
env
.
PORT
||
5000
// User.js에서 만든 model을 가져옴
const
{
User
}
=
require
(
'./models/User'
)
//const { User } = require('./')
const
path
=
require
(
"path"
);
const
cors
=
require
(
'cors'
)
// body-parser 가져옴
const
bodyParser
=
require
(
'body-parser'
)
// bodyParser option
app
.
use
(
bodyParser
.
urlencoded
({
extended
:
true
}))
//application/x-www-form-urlencoded로 된 데이터를 분석해서 가져옴
app
.
use
(
bodyParser
.
json
())
// application/json 타입으로 된 데이터를 분석해서 가져옴
const
cookieParser
=
require
(
"cookie-parser"
);
app
.
use
(
cookieParser
());
const
config
=
require
(
"./config/key"
);
const
config
=
require
(
'./config/key'
)
const
cookieParser
=
require
(
'cookie-parser'
)
app
.
use
(
cookieParser
())
const
mongoose
=
require
(
"mongoose"
);
const
mongoose
=
require
(
'mongoose'
)
const
{
auth
}
=
require
(
'./middleware/auth'
)
//이 정보는 비밀임..! 몽고DB아이디랑 비밀번호를 감춰야해..!
mongoose
.
connect
(
config
.
mongoURI
,
{
useNewUrlParser
:
true
,
useUnifiedTopology
:
true
,
useCreateIndex
:
true
,
useFindAndModify
:
false
}).
then
(()
=>
console
.
log
(
'MongoDB Connected...'
))
.
catch
(
err
=>
console
.
log
(
err
))
app
.
get
(
'/'
,
(
req
,
res
)
=>
{
res
.
send
(
'민정이짱짱맨최고최고!'
)
})
// 회원가입 구현
// route의 endpoint는 register
app
.
post
(
'/api/users/register'
,
(
req
,
res
)
=>
{
// 회원가입할 때 필요한 정보들을 client에서 가져오면
// 그것들을 데이터베이스에 넣어준다.
const
user
=
new
User
(
req
.
body
)
// req.body에 User의 정보를 저장
// 비밀번호 암호화
const
connect
=
mongoose
.
connect
(
config
.
mongoURI
,
{
useNewUrlParser
:
true
,
useUnifiedTopology
:
true
,
useCreateIndex
:
true
,
useFindAndModify
:
false
})
.
then
(()
=>
console
.
log
(
'MongoDB ---> Connected'
))
.
catch
(
err
=>
console
.
log
(
err
));
// mongoDB에서 오는 메서드. 정보들이 user model에 저장
user
.
save
((
err
,
userInfo
)
=>
{
// 만약 에러가 나면, json형식으로 success:false를 보내주고, 에러메시지를 보내줌
if
(
err
)
return
res
.
json
({
success
:
false
,
err
})
// 성공하면 status(200) (status(200)은 성공했다는 뜻)
return
res
.
status
(
200
).
json
({
success
:
true
})
})
app
.
use
(
cors
())
})
// 로그인 구현 -> 로그인 하면 토큰 생성
app
.
post
(
'/api/users/login'
,
(
req
,
res
)
=>
{
// 1. 요청된 이메일이 데이터베이스에 있는지 찾기
User
.
findOne
({
email
:
req
.
body
.
email
},
(
err
,
user
)
=>
{
if
(
!
user
)
{
return
res
.
json
({
loginSuccess
:
false
,
message
:
"There is no user with that email."
})
}
// 2. email과 비밀번호가 맞는지 확인 (User.js에 comparePassword 함수 정의되어 있음)
user
.
comparePassword
(
req
.
body
.
password
,
(
err
,
isMatch
)
=>
{
if
(
!
isMatch
)
return
res
.
json
({
loginSuccess
:
false
,
message
:
"Password is not match."
})
// 3. 비밀번호까지 맞다면 유저를 위한 토큰 생성 (User.js에 generateToken 함수 정의)
user
.
generateToken
((
err
,
user
)
=>
{
// err가 없으면 user에 정보 받아옴
if
(
err
)
return
res
.
status
(
400
).
send
(
err
);
// 4. 생성한 토큰을 저장함 -> 쿠키나 로컬 스토리지 등에 저장할 수 있는데 여기선 쿠키에 저장
res
.
cookie
(
"loginCookie"
,
user
.
token
)
.
status
(
200
)
//성공했다는 표시
.
json
({
loginSuccess
:
true
,
userId
:
user
.
_id
})
})
})
})
})
app
.
use
(
'/api/users'
,
require
(
'./routes/users'
));
// 인증 구현 (이 사람이 일반유저인지 관리자인지)
app
.
get
(
'/api/users/auth'
,
auth
,(
req
,
res
)
=>
{
// 여기까지 미들웨어(auth) 통과했으면 authentication == true 라는 뜻
res
.
status
(
200
).
json
({
_id
:
req
.
user
.
_id
,
isAdmin
:
req
.
user
.
role
===
0
?
false
:
true
,
// role이 0이면 일반 유저, role이 0이 아니면 관리자.
isAuth
:
true
,
email
:
req
.
user
.
email
,
lastname
:
req
.
user
.
lastname
,
role
:
req
.
user
.
role
,
image
:
req
.
user
.
image
})
})
// 로그아웃 구현 (로그인 때 만든 토큰을 지워버림)
app
.
get
(
'/api/users/logout'
,
auth
,
(
req
,
res
)
=>
{
User
.
findOneAndUpdate
({
_id
:
req
.
user
.
_id
},
// id로 User를 찾아서 업데이터 시킴
{
token
:
""
},
(
err
,
user
)
=>
{
if
(
err
)
return
res
.
json
({
success
:
false
,
err
});
return
res
.
status
(
200
).
send
({
success
:
true
})
})
})
// 이미지 가져오려고
app
.
use
(
'/uploads'
,
express
.
static
(
'uploads'
));
// test
app
.
get
(
'/api/hello'
,
(
req
,
res
)
=>
{
res
.
send
(
"hello"
);
})
if
(
process
.
env
.
NODE_ENV
===
"production"
)
{
app
.
use
(
express
.
static
(
"client/build"
));
app
.
get
(
"*"
,
(
req
,
res
)
=>
{
res
.
sendFile
(
path
.
resolve
(
__dirname
,
"../client"
,
"build"
,
"index.html"
));
});
}
app
.
listen
(
port
,
()
=>
{
console
.
log
(
`Example app listening at http://localhost:
${
port
}
`
)
})
\ No newline at end of file
console
.
log
(
`Server ---> http://localhost:
${
port
}
`
)
});
\ No newline at end of file
...
...
We-Shop/server/middleware/auth.js
View file @
1fb939e
const
{
User
}
=
require
(
"../models/User"
);
const
{
User
}
=
require
(
'../models/User'
);
let
auth
=
(
req
,
res
,
next
)
=>
{
// 인증 처리
// 1. client 쿠키에서 토큰을 가져옴.
let
token
=
req
.
cookies
.
loginCookie
;
// 인증 처리
// 1. client 쿠키에서 토큰을 가져옴.
let
token
=
req
.
cookies
.
w_auth
;
// 2. 토큰을 복호화한 후 유저를 찾는다. (User.js에 findByToken(); 있음)
User
.
findByToken
(
token
,
(
err
,
user
)
=>
{
// 에러가 있으면
if
(
err
)
throw
err
;
// 유저가 없으면
if
(
!
user
)
return
res
.
json
({
isAuth
:
false
,
error
:
true
})
// 에러도 없고 유저도 있으면
req
.
token
=
token
;
// token과 user를 request에 넣어줌으로써 index.js에서 request 사용할 수 있음
req
.
user
=
user
;
next
();
});
// 2. 토큰을 복호화한 후 유저를 찾는다. (User.js에 findByToken(); 있음)
User
.
findByToken
(
token
,
(
err
,
user
)
=>
{
// 에러가 있으면
if
(
err
)
throw
err
;
// 유저가 없으면
if
(
!
user
)
return
res
.
json
({
isAuth
:
false
,
error
:
true
})
// 에러도 없고 유저도 있으면
req
.
token
=
token
;
// token과 user를 request에 넣어줌으로써 index.js에서 request 사용할 수 있음
req
.
user
=
user
;
next
();
});
// 3. 유저가 있으면 인증OK, 유저가 없으면 인증No!
// 3. 유저가 있으면 인증OK, 유저가 없으면 인증No!
}
// 이 auth를 다른 파일에서도 쓸 수 있도록
...
...
We-Shop/server/models/User.js
View file @
1fb939e
...
...
@@ -5,35 +5,36 @@ const bcrypt = require('bcrypt')
// bcrypt 사용하기 위해 salt를 생성하고 그걸 이용해 암호화 시킴
const
saltRounds
=
10
// salt를 몇글자 할 건지
//
const
jwt
=
require
(
'jsonwebtoken'
)
const
jwt
=
require
(
'jsonwebtoken'
);
const
moment
=
require
(
"moment"
);
const
userSchema
=
mongoose
.
Schema
({
name
:{
type
:
String
,
maxlength
:
50
name
:
{
type
:
String
,
maxlength
:
50
},
email
:{
type
:
String
,
trim
:
true
,
// 'minjeong park'처럼 space가 있는 문자에 space가 없어지도록 함
unique
:
1
// 똑같은 이메일은 쓸 수 없도록
email
:
{
type
:
String
,
trim
:
true
,
unique
:
1
},
password
:
{
type
:
String
,
min
length
:
5
min
glength
:
3
},
lastname
:
{
type
:
String
,
type
:
String
,
maxlength
:
50
},
role
:
{
// Number==1 이면 관리자, number==0 이면 일반 유저
type
:
Number
,
default
:
0
// default는 0
role
:
{
type
:
Number
,
// Number==1 이면 관리자, number==0 이면 일반 유저
default
:
0
// default는 0
},
image
:
String
,
token
:
{
type
:
String
type
:
String
,
},
tokenExp
:
{
//토큰의 유효기간
tokenExp
:{
type
:
Number
}
})
...
...
@@ -41,11 +42,11 @@ const userSchema = mongoose.Schema({
// index.js의 app.post('/register', (req, res)에 있는
// user model에 user 정보를 저장하기 전에 무엇을 한다는 것
// function( next )를 해서 얘네가 끝난 다음에 다음걸 실행해라~
userSchema
.
pre
(
'save'
,
function
(
next
){
var
user
=
this
if
(
user
.
isModified
(
'password'
))
// password를 변경할 때만 적용되도록..
{
userSchema
.
pre
(
'save'
,
function
(
next
)
{
var
user
=
this
;
if
(
user
.
isModified
(
'password'
))
{
// password를 변경할 때만 적용되도록..
// 비밀번호 암호화 (https://www.npmjs.com/package/bcrypt 에서 가져옴)
bcrypt
.
genSalt
(
saltRounds
,
(
err
,
salt
)
=>
// salt를 만드는 함수
{
...
...
@@ -53,18 +54,15 @@ userSchema.pre('save', function( next ){
bcrypt
.
hash
(
user
.
password
,
salt
,
(
err
,
hash
)
=>
{
// bcrypt.hash(암호화되지 않은 pw, salt, function(err, 암호화된 비밀번호))
if
(
err
)
return
next
(
err
)
// 에러 나면 return err
user
.
password
=
hash
// 성공하면 user.password를 hash로 교체
next
()
});
});
}
else
{
next
()
})
})
}
else
{
next
()
}
});
})
userSchema
.
methods
.
comparePassword
=
function
(
plainPassword
,
cb
){
userSchema
.
methods
.
comparePassword
=
function
(
plainPassword
,
cb
){
// 1. plainPassword가 1234567 암호화된 비밀번호 가 같은지 체크해야함
// 그러면 plainPassword도 암호화해서 비교해야함. (복호화 할 수 없기 때문에)
...
...
@@ -75,39 +73,35 @@ userSchema.methods.comparePassword = function(plainPassword, cb){
})
}
userSchema
.
methods
.
generateToken
=
function
(
cb
)
{
userSchema
.
methods
.
generateToken
=
function
(
cb
)
{
var
user
=
this
;
// jsonwebtoken을 이용해서 token 생성
var
token
=
jwt
.
sign
(
user
.
_id
.
toHexString
(),
'secretToken'
)
//database에 있는 id라서 _id
var
oneHour
=
moment
().
add
(
1
,
'hour'
).
valueOf
();
user
.
token
=
token
user
.
save
(
function
(
err
,
user
){
if
(
err
)
return
cb
(
err
)
// 에러가 있다면 callback으로 에러 전달
user
.
token
Exp
=
oneHour
;
user
.
token
=
token
;
user
.
save
(
function
(
err
,
user
){
if
(
err
)
return
cb
(
err
)
// 에러가 있다면 callback으로 에러 전달
cb
(
null
,
user
)
// 에러가 없다면 err는 없고 user정보만 전달
})
}
userSchema
.
statics
.
findByToken
=
function
(
token
,
cb
)
{
userSchema
.
statics
.
findByToken
=
function
(
token
,
cb
)
{
var
user
=
this
;
// 1. 토큰을 decoding
jwt
.
verify
(
token
,
'secretToken'
,
function
(
err
,
decoded
)
{
// 2. 유저 아이디를 이용해서 유저를 찾은 다음에 클라이언트에서 가져온 토큰과 DB에 보관된 토큰이 일치하는지 확인.
user
.
findOne
({
"_id"
:
decoded
,
"token"
:
token
},
function
(
err
,
user
){
// findOne :: mongoDB에 이미 있는 method
// 에러가 나면
if
(
err
)
return
cb
(
err
);
// 에러가 안나면
cb
(
null
,
user
)
})
})
// 2. 유저 아이디를 이용해서 유저를 찾은 다음에 클라이언트에서 가져온 토큰과 DB에 보관된 토큰이 일치하는지 확인.
user
.
findOne
({
"_id"
:
decoded
,
"token"
:
token
},
function
(
err
,
user
){
// findOne :: mongoDB에 이미 있는 method
// 에러가 나면
if
(
err
)
return
cb
(
err
);
// 에러가 안나면
cb
(
null
,
user
)
})
})
}
// 만든 스키마를 모델로 감싸줌
const
User
=
mongoose
.
model
(
'User'
,
userSchema
)
const
User
=
mongoose
.
model
(
'User'
,
userSchema
);
// 이 모델을 다른 파일에서도 쓰고싶으면 아래와 같이 해주면 됨
module
.
exports
=
{
User
}
\ No newline at end of file
module
.
exports
=
{
User
}
\ No newline at end of file
...
...
We-Shop/server/routes/users.js
0 → 100644
View file @
1fb939e
const
express
=
require
(
'express'
);
const
{
User
}
=
require
(
"../models/User"
);
const
{
auth
}
=
require
(
"../middleware/auth"
);
const
router
=
express
.
Router
();
router
.
get
(
"/auth"
,
auth
,
(
req
,
res
)
=>
{
res
.
status
(
200
).
json
({
_id
:
req
.
user
.
_id
,
isAdmin
:
req
.
user
.
role
===
0
?
false
:
true
,
isAuth
:
true
,
email
:
req
.
user
.
email
,
name
:
req
.
user
.
name
,
lastname
:
req
.
user
.
lastname
,
role
:
req
.
user
.
role
,
image
:
req
.
user
.
image
,
});
});
router
.
post
(
"/register"
,
(
req
,
res
)
=>
{
const
user
=
new
User
(
req
.
body
);
user
.
save
((
err
,
doc
)
=>
{
if
(
err
)
return
res
.
json
({
success
:
false
,
err
});
return
res
.
status
(
200
).
json
({
success
:
true
});
});
});
router
.
post
(
"/login"
,
(
req
,
res
)
=>
{
User
.
findOne
({
email
:
req
.
body
.
email
},
(
err
,
user
)
=>
{
if
(
!
user
)
return
res
.
json
({
loginSuccess
:
false
,
message
:
"Auth failed, email not found"
});
user
.
comparePassword
(
req
.
body
.
password
,
(
err
,
isMatch
)
=>
{
if
(
!
isMatch
)
return
res
.
json
({
loginSuccess
:
false
,
message
:
"Wrong password"
});
user
.
generateToken
((
err
,
user
)
=>
{
if
(
err
)
return
res
.
status
(
400
).
send
(
err
);
res
.
cookie
(
"w_authExp"
,
user
.
tokenExp
);
res
.
cookie
(
"w_auth"
,
user
.
token
)
.
status
(
200
)
.
json
({
loginSuccess
:
true
,
userId
:
user
.
_id
});
});
});
});
});
router
.
get
(
"/logout"
,
auth
,
(
req
,
res
)
=>
{
User
.
findOneAndUpdate
({
_id
:
req
.
user
.
_id
},
{
token
:
""
,
tokenExp
:
""
},
(
err
,
doc
)
=>
{
if
(
err
)
return
res
.
json
({
success
:
false
,
err
});
return
res
.
status
(
200
).
send
({
success
:
true
});
});
});
module
.
exports
=
router
;
Please
register
or
login
to post a comment