Menu
CoddyTech

登録のルール

CoddyのNode.jsジャーニー「認証とセキュリティ」セクションの一部。レッスン 7/24。

現時点では、誰でも同じ名前で二度登録したり、パスワードに 1 を使って登録したりできます。登録処理では、何かを保存する前に、受け取った内容を確認する必要があります。

問題の内容を示すステータスコードが2つあります。400 Bad Request は、短すぎるパスワードのように、リクエスト自体が受け付けられないことを意味します。409 Conflict は、すでに使われている名前のように、既存のデータと競合することを意味します。

名前の表記も統一する必要があります。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

チャレンジ

簡単

現状では、誰でも同じ名前で2回登録したり、パスワードに 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が返されます。
  • POST /signup に {"password": "correct horse"} だけを送信します。この場合もステータス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プレイグラウンド