Wecode - Project 2 (부트캠프)/Project 2 과정

Project 2- 5일차 (1): 내가 짠 [회원가입 API 및 설명]

JBS 12 2023. 9. 22. 08:57

내가 작성한 

const express = require('express');
const morgan = require('morgan');
const cors = require('cors');

require('dotenv').config();

const app = express();

app.set('port', process.env.PORT || 8000);
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.use((req, _, next) => {
const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
error.status = 404;
next(error);
});

app.use((err, _, res, next) => {
res.status(err.status || 500);
return res.json({
error: `${err.status ? err.status : ''} ${err.message}`,
});
});

app.listen(app.get('port'), () => {
console.log(`listening.... 🦻http://localhost:${app.get('port')}`);
});


// 회원가입
app.post("/users", async (req, res) => {
try {
const me = req.body;
console.log(me);

const password = me.password;
const email = me.email;

// key error (필수 입력 정보 없을 경우)
if ( username === undefined || userid === undefined
|| password === undefined || birthdate === undefined
|| email === undefined || phonenumber === undefined
|| gender === undefined) {
const error = new Error("KEY_ERROR");
error.statusCode = 400;
throw error;
}

// 이메일 중복 확인, 있으면 에러
const existingUser = await myDataSource.query(`
SELECT daterbaseId, email FROM users WHERE email='${email}';
`);

console.log("existing user:", existingUser);
if (existingUser.length > 0) {
const error = new Error("이미 존재하는 사용자입니다");
error.statusCode = 400;
throw error;
}


// email . @ 필수 포함 정규식 (프론트와 협의)
const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;

if (!emailRegex.test(email)) {
const error = new Error("유효하지 않은 이메일 주소 형식입니다.");
error.statusCode = 400;
throw error;
}

// 비밀번호 8자리 이상
if (password.length < 8) {
const error = new Error("패스워드는 8자리 이상이어야 합니다");
error.statusCode = 400;
throw error;
}

// 아이디 : 공백 없는 영문/숫자 포함, 6자리 이상
if (userId.length < 6) {
const error = new Error("아이디는 6자리 이상이어야 합니다");
error.statusCode = 400;
throw error;
}

if (!/^[a-zA-Z0-9]+$/.test(userId)) {
const error = new Error('아이디는 영문자와 숫자를 포함해야 합니다.');
error.statusCode = 400;
throw error;
}

if (!userId.trim()) {
const error = new Error('사용자 아이디에 공백이 있습니다.');
error.statusCode = 400;
throw error;
}


// DB에 회원정보 저장
const addUser = await myDataSource.query(`
INSERT INTO users (
userName,userId,
password, birthDate,
email, phoneNumber, gender,
recommender
)
VALUES (
'${userName}',
'${userId}',
'${password}',
'${birthDate}',
'${password}',
'${email}',
'${phoneNumber}',
'${gender}',
'${recommender}'
)
`);
//선택사항 'recommender'도 기입 시 저장돼야 하니까 여기에 추가?

return res.status(201).json({
message: "회원가입이 완료되었습니다",
});
} catch (error) {
console.log(error);
return res.status(error.statusCode).json({
message: "회원가입에 실패하였습니다",
});
}
});

 

// key error (필수 입력 정보 없을 경우)


if ( username === undefined || userid === undefined
|| password === undefined || birthdate === undefined
|| email === undefined || phonenumber === undefined
|| gender === undefined) {
const error = new Error("KEY_ERROR");
error.statusCode = 400;
throw error;
}

치면서 의문점: 한번에 합칠 수 있는 방법이 없을지 

--> 'username === undefined' 는
'!username' 으로 축약


// 이메일 중복 확인, 있으면 에러


const existingUser = await myDataSource.query(`
SELECT daterbaseId, email FROM users WHERE email='${email}';
`);
--> daterbaseID > id 로 수정되어야 함
console.log("existing user:", existingUser);
if (existingUser.length > 0) {
const error = new Error("이미 존재하는 사용자입니다"); 
error.statusCode = 400;
throw error;
}

 

** 고려한 점: ID를 구분. 

database에 들어가는 ID = daterbaseId

회원가입 시 유저가 기입하는 '아이디' = userID 

 

치면서 의문점: 
이전 다른 과제 코드에서는 id, email을 넣었는데,

1) id가 왜 필요한지,
2) 우리 사이트에서는 userID가 있어서, ID를 daterbase ID로 구분함.  이게 맞는지 
---> databaseId라는 걸 우리가 erd diagram에 정의 안 해서 안 보일 것. 
-->id 헷갈리니 아이디 빼자! 
3) 카멜 케이스와 스네이크 케이스 --> 이거는 추후 공부  (peer reviwe)

4)근데 select * FROM users WHERE email = '${email}' 
하면 안되는지? 
--> 최대한, * 은 안 쓰는 게 좋음. 쓰지 않을 데이터까지 다 가져오는 데이터 낭비가 되니까. 
-->  select id, email FROM users WHERE email =  '${email}' 

// email . @ 필수 포함 정규식 (프론트와 협의)


const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;

if (!emailRegex.test(email)) {
const error = new Error("유효하지 않은 이메일 주소 형식입니다.");
error.statusCode = 400;
throw error;
}

 

치면서 의문점: 
chatgpt의 도움을 받았기에.. 
(테크리더도 그렇게 한다고 괜찮다고 ㅎ) 

// 비밀번호 8자리 이상


if (password.length < 8) {
const error = new Error("패스워드는 8자리 이상이어야 합니다");
error.statusCode = 400;
throw error;
}

치면서 의문점: 없음

// 아이디 : 공백 없는 영문/숫자 포함, 6자리 이상

치면서 의문점: 
나는 이것을 3개의 코드로 나누어서 했다. 

이게 맞는지

1)  아이디 6자리 이상 


if (userId.length < 6) {
const error = new Error("아이디는 6자리 이상이어야 합니다");
error.statusCode = 400;
throw error;
}

 


2)  아이디 영문/숫자 포함


if (!/^[a-zA-Z0-9]+$/.test(userId)) {
const error = new Error('아이디는 영문자와 숫자를 포함해야 합니다.');
error.statusCode = 400;
throw error;
}

 

치면서 의문점: 

3)  아이디 공백 없음


if (!userId.trim()) {
const error = new Error('사용자 아이디에 공백이 있습니다.');
error.statusCode = 400;
throw error;
}

 

if (!userId.trim()) {
  console.error('사용자 아이디에 공백이 있습니다.');
  // 에러 처리: 사용자 아이디에 공백이 있을 경우 에러를 처리하거나 예외를 throw할 수 있습니다.
  // 예외를 throw하면 아래 catch 블록에서 처리됩니다.
}

 

위 코드에서 if (!userId.trim()) 조건문은 사용자 아이디에 공백이 있는지 검사합니다.

trim() 메서드를 사용하여 문자열의 앞뒤 공백을 제거하고,

그 결과가 빈 문자열("")이라면 사용자 아이디에 공백이 있음을 나타냅니다.

이 조건을 만족하면 에러 메시지를 출력하고, 원하는 방식으로 에러를 처리할 수 있습니다.

만약 에러를 더 구체적으로 처리하려면 throw 문을 사용하여 예외를 throw하고, 호출자에서 해당 예외를 처리할 수 있습니다.

 

 

이 코드는 사용자가 입력한 아이디(userId)에 대한 검증을 수행하는 부분입니다. 

이 코드는 아래와 같이 동작합니다:

userId.trim()

trim() 메서드는 문자열 앞뒤의 공백을 제거한 새로운 문자열을 반환합니다. 예를 들어, " myuser123 " 문자열을 myuser123로 변경합니다. 만약 userId에 공백 문자만 있거나 빈 문자열("")이라면, trim() 메서드를 통해 모든 공백이 제거된 결과가 빈 문자열이 됩니다.

if (!userId.trim())

 trim()을 통해 얻은 결과를 if 문으로 검사합니다. ! 연산자는 값을 부정합니다. 따라서 userId에 공백 문자만 있거나 빈 문자열인 경우, !userId.trim()는 true가 됩니다. 이것은 사용자 아이디에 공백이 있음을 나타냅니다.

console.error('사용자 아이디에 공백이 있습니다.');

 if 문이 true일 때, 콘솔에 에러 메시지를 출력합니다. 이 메시지는 사용자에게 사용자 아이디에 공백이 있음을 알리는 용도로 사용됩니다.

즉, 위 코드는 사용자가 입력한 아이디(userId)가 공백만으로 이루어져 있거나 빈 문자열인 경우에 대한 검증을 수행하고, 해당 조건을 만족할 때 에러 메시지를 출력합니다. 이렇게 함으로써 사용자가 유효하지 않은 아이디를 제출한 경우에 대비할 수 있습니다.

 

 

치면서 의문점: 

// DB에 회원정보 저장


const addUser = await myDataSource.query(`
INSERT INTO users (
userName,userId,
password, birthDate,
email, phoneNumber, gender,
recommender
)
VALUES (
'${userName}',
'${userId}',
'${password}',
'${birthDate}',
'${password}',
'${email}',
'${phoneNumber}',
'${gender}',
'${recommender}'
)
`);

치면서 의문점:
선택사항 'recommender'도 기입 시 저장돼야 하니까 여기에 추가?

---> 테크리더가 이거는 안하는게 좋겠다고. 칼럼을 추가 만들어야 하니까.


return res.status(201).json({
message: "회원가입이 완료되었습니다",
});
} catch (error) {
console.log(error);
return res.status(error.statusCode).json({
message: "회원가입에 실패하였습니다",
});
}
});