Menu
CoddyTech

가입 규칙

Coddy Node.js 여정의 인증과 보안 섹션에 포함된 레슨. 24개 중 7번째.

현재는 누구나 같은 이름으로 두 번 가입하거나, 비밀번호를 1로 설정할 수 있습니다. 가입 처리에서는 어떤 데이터든 저장하기 전에 받은 내용을 확인해야 합니다.

무엇이 잘못되었는지 알려 주는 상태 코드가 두 가지 있습니다. 400 잘못된 요청은 비밀번호가 너무 짧은 경우처럼 요청 자체가 허용되지 않음을 의미합니다. 409 충돌은 이미 보유한 데이터와 충돌함을 의미하며, 예를 들어 이미 사용 중인 이름이 이에 해당합니다.

이름의 표기도 통일해야 합니다. Ada와 ada는 읽는 사람에게 같은 사람처럼 보이므로, 이름을 저장하기 전과 조회하기 전에 소문자로 바꾸세요:

const email = String(req.body.email ?? '').trim().toLowerCase();
if (await subscribers.findOne({ email })) {
    return res.status(409).json({ error: 'Already subscribed' });
}
challenge icon

챌린지

쉬움

현재 누구나 같은 이름이나 비밀번호 1로 두 번 가입할 수 있습니다. 가입 과정에서 어떤 내용이 저장되기 전에 입력값을 확인하도록 만드세요.

  1. server.js의 POST /signup 시작 부분에서 사용자 이름을 정리하세요. 앞뒤 공백을 제거하고 소문자로 바꿔서 " Ada "가 "ada"가 되도록 하세요. 사용자 이름이 없으면 빈 이름으로 처리하세요.
  2. 계속해서 POST /signup에서 이름이 비어 있거나 비밀번호가 8자 미만이면 상태 코드 400과 {"error": "Pick a username and a password of at least 8 characters"}를 응답하세요. 정확히 8자인 비밀번호는 충분히 깁니다.
  3. 정리한 이름을 가진 사용자가 이미 있으면 상태 코드 409와 {"error": "That username is taken"}을 응답하세요.
  4. 그렇지 않으면 소문자 이름으로 사용자를 저장하세요. 201 응답에는 저장된 이름이 표시됩니다. 요청에 "Ada"라고 적혀 있어도 {"username": "ada"}가 표시됩니다.
  5. POST /login에서도 사용자를 찾기 전에 같은 방식으로 사용자 이름을 정리하세요. 그러면 ADA로 ada 계정에 로그인할 수 있습니다.

직접 해 보기: ‘실행’을 누르세요.

  • POST /signup에 {"username": "Ada", "password": "correct horse"}를 보내세요. 상태 코드 201과 {"username": "ada"}가 응답됩니다.
  • POST /signup에 {"username": "ada", "password": "another password"}를 보내세요. 상태 코드 409와 "taken" 오류가 응답됩니다.
  • POST /login에 {"username": "ADA", "password": "correct horse"}를 보내세요. 상태 코드 200과 {"username": "ada"}가 응답됩니다.
  • POST /signup에 {"username": "bob", "password": "1234"}를 보내세요. 상태 코드 400이 응답됩니다.
  • {"password": "correct horse"}만 POST /signup에 보내도 상태 코드 400이 응답됩니다.

직접 해보기

import express from 'express';
import { users } from './db.js';
import { hashPassword, verifyPassword } from './passwords.js';

const app = express();
app.use(express.json());

app.post('/signup', async (req, res) => {
    const { username, password } = req.body;
    await users.insertOne({ username, passwordHash: await hashPassword(password) });
    res.status(201).json({ username });
});

app.post('/login', async (req, res) => {
    const { username, password } = req.body;
    const user = await users.findOne({ username });
    if (!user || !(await verifyPassword(password, user.passwordHash))) {
        return res.status(401).json({ error: 'Wrong username or password' });
    }
    res.json({ username: user.username });
});

// signup에서 저장한 내용을 보여줍니다. 학습용으로만 사용합니다. 실제 앱에는 이 경로가 없습니다.
app.get('/debug/users/:username', async (req, res) => {
    const user = await users.findOne({ username: req.params.username });
    res.json(user ? { username: user.username, passwordHash: user.passwordHash } : null);
});

app.listen(3000, () => {
    console.log('Vault is running on port 3000');
});
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

인증과 보안의 모든 레슨

직접 연습해 보세요: Express 플레이그라운드