-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[FEAT] checkUser 미들웨어 구현
- Loading branch information
Showing
12 changed files
with
1,690 additions
and
3,490 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
const functions = require('firebase-functions'); | ||
const admin = require('firebase-admin'); | ||
const util = require('../../../lib/util'); | ||
const statusCode = require('../../../constants/statusCode'); | ||
const responseMessage = require('../../../constants/responseMessage'); | ||
const db = require('../../../db/db'); | ||
const { userDB } = require('../../../db'); | ||
const jwtHandlers = require('../../../lib/jwtHandlers'); | ||
|
||
/** | ||
* @회원가입 | ||
* @route POST /auth/signup | ||
* @body socialId:string, nickname:string, profileImg:file | ||
* @error | ||
* 1. socialId/nickname이 전달되지 않음 | ||
* 2. 이미 존재하는 socialId | ||
* 3. 닉네임 10자 초과 | ||
*/ | ||
|
||
module.exports = async (req, res) => { | ||
const { socialId, nickname } = req.body; | ||
const profileImg = req.imageUrls; | ||
|
||
console.log(socialId, nickname, profileImg); | ||
|
||
// @error 1. socialId/nickname이 전달되지 않음 | ||
if (!socialId || !nickname) { | ||
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.NULL_VALUE)); | ||
} | ||
|
||
let client; | ||
|
||
try { | ||
client = await db.connect(); | ||
|
||
// @error 2. 이미 존재하는 socialIds | ||
const alreaySocialId = await userDB.getUserBySocialId(client, socialId); | ||
if(alreaySocialId) { | ||
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.ALREADY_SOCIALID)); | ||
} | ||
|
||
let user; | ||
|
||
if (profileImg.length) { | ||
user = await userDB.addUser(client, socialId, nickname, profileImg[0]); | ||
} else { | ||
user = await userDB.addUser(client, socialId, nickname, null); | ||
} | ||
|
||
const { accesstoken } = jwtHandlers.sign(user); | ||
|
||
console.log(user); | ||
|
||
res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.CREATED_USER, { user, accesstoken })); | ||
} catch (error) { | ||
console.log(error); | ||
functions.logger.error(`[SIGNUP ERROR] [${req.method.toUpperCase()}] ${req.originalUrl}`, `[CONTENT] email:${socialId} ${error}`); | ||
|
||
res.status(statusCode.INTERNAL_SERVER_ERROR).send(util.fail(statusCode.INTERNAL_SERVER_ERROR, responseMessage.INTERNAL_SERVER_ERROR)); | ||
} finally { | ||
client.release(); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const functions = require('firebase-functions'); | ||
const admin = require('firebase-admin'); | ||
const util = require('../../../lib/util'); | ||
const statusCode = require('../../../constants/statusCode'); | ||
const responseMessage = require('../../../constants/responseMessage'); | ||
const db = require('../../../db/db'); | ||
const { userDB } = require('../../../db'); | ||
const jwtHandlers = require('../../../lib/jwtHandlers'); | ||
|
||
|
||
module.exports = async (req, res) => { | ||
const user = req.user; | ||
console.log(user); | ||
if (!user) return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.NO_USER)); | ||
|
||
let client; | ||
|
||
try { | ||
client = await db.connect(); | ||
|
||
res.status(statusCode.OK).send(util.success(statusCode.OK, "token -> user 활용법", user)); | ||
} catch (error) { | ||
console.log(error); | ||
functions.logger.error(`[ERROR] [${req.method.toUpperCase()}] ${req.originalUrl}`, `[CONTENT] ${error}`); | ||
|
||
res.status(statusCode.INTERNAL_SERVER_ERROR).send(util.fail(statusCode.INTERNAL_SERVER_ERROR, responseMessage.INTERNAL_SERVER_ERROR)); | ||
} finally { | ||
client.release(); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
const express = require('express'); | ||
const router = express.Router(); | ||
const uploadImage = require('../../../middlewares/uploadImage'); | ||
const { checkUser } = require('../../../middlewares/auth'); | ||
|
||
// router.post('/signup', require('./userSignupPOST')); | ||
router.post('/signup',uploadImage, require('./authSignupPOST')); | ||
// router.get('/test', checkUser, require('./authTestGET')); | ||
router.get('/test', checkUser, require('./authTestGET')); | ||
|
||
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
const TOKEN_EXPIRED = -3; | ||
const TOKEN_INVALID = -2; | ||
|
||
module.exports = { | ||
TOKEN_EXPIRED, | ||
TOKEN_INVALID, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,4 +78,4 @@ const connect = async (req) => { | |
|
||
module.exports = { | ||
connect, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,42 @@ | ||
const _ = require('lodash'); | ||
const convertSnakeToCamel = require('../lib/convertSnakeToCamel'); | ||
|
||
const getAllUsers = async (client) => { | ||
const { rows } = await client.query( | ||
` | ||
SELECT * FROM "user" u | ||
WHERE is_deleted = FALSE | ||
`, | ||
); | ||
return convertSnakeToCamel.keysToCamel(rows); | ||
}; | ||
|
||
const getUserById = async (client, userId) => { | ||
const { rows } = await client.query( | ||
` | ||
SELECT * FROM "user" u | ||
WHERE id = $1 | ||
SELECT * FROM spark.user u | ||
WHERE user_id = $1 | ||
AND is_deleted = FALSE | ||
`, | ||
// client.query()의 두 번째 파라미터에는, 쿼리문에 집어넣고 싶은 변수들의 배열을 적습니다. | ||
// $1에는 배열의 첫번째 변수가, $2에는 배열의 두 번째 변수... 이런 식으로 쿼리문에 변수가 들어가게 됩니다! | ||
[userId], | ||
); | ||
// 위의 getAllUsers와는 달리, 이번에는 유저 하나만 가져오고 싶기 때문에 rows[0]만 리턴해 줍니다. | ||
return convertSnakeToCamel.keysToCamel(rows[0]); | ||
}; | ||
} | ||
|
||
const getUserByIdFirebase = async (client, idFirebase) => { | ||
const getUserBySocialId = async (client, socialId) => { | ||
const { rows } = await client.query( | ||
` | ||
SELECT * FROM "user" u | ||
WHERE id_firebase = $1 | ||
SELECT * FROM spark.user u | ||
WHERE social_id = $1 | ||
AND is_deleted = FALSE | ||
`, | ||
[idFirebase], | ||
[socialId], | ||
); | ||
return convertSnakeToCamel.keysToCamel(rows[0]); | ||
}; | ||
|
||
const getUserByEmail = async (client, email) => { | ||
const addUser = async (client, socialId, nickname, profileImg) => { | ||
const { rows } = await client.query( | ||
` | ||
SELECT * FROM "user" u | ||
WHERE email = $1 | ||
AND is_deleted = FALSE | ||
`, | ||
[email], | ||
); | ||
return convertSnakeToCamel.keysToCamel(rows[0]); | ||
}; | ||
|
||
const updateUser = async (client, username, phone, userId) => { | ||
const { rows: existingRows } = await client.query( | ||
` | ||
SELECT * FROM "user" | ||
WHERE id = $1 | ||
AND is_deleted = FALSE | ||
`, | ||
[userId], | ||
); | ||
|
||
if (existingRows.length === 0) return false; | ||
|
||
const data = _.merge({}, convertSnakeToCamel.keysToCamel(existingRows[0]), { username, phone }); | ||
|
||
const { rows } = await client.query( | ||
` | ||
UPDATE "user" u | ||
SET username = $1, phone = $2, updated_at = now() | ||
WHERE id = $3 | ||
RETURNING * | ||
`, | ||
[data.username, data.phone, userId], | ||
); | ||
return convertSnakeToCamel.keysToCamel(rows[0]); | ||
}; | ||
|
||
const deleteUser = async (client, userId) => { | ||
const { rows } = await client.query( | ||
` | ||
UPDATE "user" u | ||
SET is_deleted = TRUE, updated_at = now() | ||
WHERE id = $1 | ||
RETURNING * | ||
`, | ||
[userId], | ||
); | ||
|
||
return convertSnakeToCamel.keysToCamel(rows[0]); | ||
}; | ||
|
||
const addUser = async (client, email, username, phone, idFirebase) => { | ||
const { rows } = await client.query( | ||
` | ||
INSERT INTO "user" | ||
(email, username, phone, id_firebase) | ||
INSERT INTO spark.user | ||
(social_id, nickname, profile_img) | ||
VALUES | ||
($1, $2, $3, $4) | ||
RETURNING * | ||
($1, $2, $3) | ||
RETURNING user_id, nickname, profile_img | ||
`, | ||
|
||
[email, username, phone, idFirebase], | ||
[socialId, nickname, profileImg], | ||
); | ||
return convertSnakeToCamel.keysToCamel(rows[0]); | ||
}; | ||
|
||
module.exports = { getAllUsers, getUserById, getUserByIdFirebase, getUserByEmail, updateUser, deleteUser, addUser }; | ||
module.exports = { getUserById, getUserBySocialId, addUser }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,48 @@ | ||
const functions = require('firebase-functions'); | ||
const jwt = require('jsonwebtoken'); | ||
const { TOKEN_INVALID, TOKEN_EXPIRED } = require('../constants/jwt'); | ||
|
||
// JWT를 발급/인증할 떄 필요한 secretKey를 설정합니다. 값은 .env로부터 불러옵니다. | ||
const secretKey = process.env.JWT_SECRET; | ||
const options = { | ||
algorithm: 'HS256', | ||
expiresIn: '30d', | ||
issuer: 'wesopt', | ||
}; | ||
|
||
// id, email, name, idFirebase가 담긴 JWT를 발급합니다. | ||
const sign = (user) => { | ||
const payload = { | ||
id: user.id, | ||
email: user.email, | ||
name: user.name || null, | ||
idFirebase: user.idFirebase, | ||
const payload = { | ||
userId: user.userId | ||
}; | ||
|
||
const result = { | ||
accesstoken: jwt.sign(payload, secretKey, options), | ||
// refreshToken: jwt.sign(payload, secretKey, refreshOptions), | ||
}; | ||
return result; | ||
}; | ||
|
||
// JWT를 해독하고, 해독한 JWT가 우리가 만든 JWT가 맞는지 확인합니다 (인증). | ||
const verify = (token) => { | ||
let decoded; | ||
try { | ||
// console.log("token:",token); | ||
decoded = jwt.verify(token, secretKey); | ||
} catch (err) { | ||
if (err.message === 'jwt expired') { | ||
console.log('expired token'); | ||
functions.logger.error('expired token'); | ||
return TOKEN_EXPIRED; | ||
} else if (err.message === 'invalid token') { | ||
console.log("decoded:", decoded); | ||
console.log('invalid token'); | ||
functions.logger.error('invalid token'); | ||
console.log(TOKEN_INVALID); | ||
return TOKEN_INVALID; | ||
} else { | ||
console.log('invalid token'); | ||
functions.logger.error('invalid token'); | ||
return TOKEN_INVALID; | ||
} | ||
} | ||
// 해독 / 인증이 완료되면, 해독된 상태의 JWT를 반환합니다. | ||
return decoded; | ||
}; | ||
|
||
module.exports = { | ||
sign, | ||
verify, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
const functions = require('firebase-functions'); | ||
const jwtHandlers = require('../lib/jwtHandlers'); | ||
const db = require('../db/db'); | ||
const util = require('../lib/util'); | ||
const statusCode = require('../constants/statusCode'); | ||
const responseMessage = require('../constants/responseMessage'); | ||
const { userDB } = require('../db'); | ||
const { TOKEN_INVALID, TOKEN_EXPIRED } = require('../constants/jwt'); | ||
|
||
const checkUser = async (req, res, next) => { | ||
|
||
let client; | ||
try { | ||
client = await db.connect(req); | ||
|
||
let user; | ||
|
||
if (!req.headers) return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.NO_AUTH_HEADER)); | ||
|
||
const token = String(req.headers.authorization || ''); | ||
if (!token) return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.TOKEN_EMPTY)); | ||
const decodedToken = jwtHandlers.verify(token); | ||
if (decodedToken === TOKEN_EXPIRED) return res.status(statusCode.UNAUTHORIZED).send(util.fail(statusCode.UNAUTHORIZED, responseMessage.TOKEN_EXPIRED)); | ||
if (decodedToken === TOKEN_INVALID) return res.status(statusCode.UNAUTHORIZED).send(util.fail(statusCode.UNAUTHORIZED, responseMessage.TOKEN_INVALID)); | ||
|
||
console.log(decodedToken); | ||
const userId = decodedToken.userId; | ||
|
||
if (!userId) return res.status(statusCode.UNAUTHORIZED).send(util.fail(statusCode.UNAUTHORIZED, responseMessage.TOKEN_INVALID)); | ||
|
||
user = await userDB.getUserById(client, userId); | ||
|
||
if (!user) return res.status(statusCode.UNAUTHORIZED).send(util.fail(statusCode.UNAUTHORIZED, responseMessage.NO_USER)); | ||
|
||
req.user = user; | ||
} catch (error) { | ||
console.log(error); | ||
res.status(statusCode.INTERNAL_SERVER_ERROR).send(util.fail(statusCode.INTERNAL_SERVER_ERROR, responseMessage.INTERNAL_SERVER_ERROR)); | ||
} finally { | ||
client.release(); | ||
} | ||
|
||
next(); | ||
}; | ||
|
||
module.exports = { checkUser }; |
Oops, something went wrong.