The Password Gameのパクリをつくる
The Password Gameとは
多種多様なパスワード要件を全て満たし正しいパスワードを作るゲームです。
セキュリティ芸人のYoutuberの方(脆弱エンジニアの日常)が取り上げていて、面白いと思ったのでパクりました。
使用技術
- Next.js v13.4.12
- TypeScript v5.1.6
- Chakra UI v2.8.0
実際にやってみる
1.フォームの作成
ChakraUIにはInputというコンポーネントが用意されてるのでこれを使います。
"use client";
import {
Box,
FormControl,
FormLabel,
Heading,
Input,
Spacer,
VStack,
} from "@chakra-ui/react";
import { useState } from "react";
const Home = () => {
const [password, setPassword] = useState<string>("");
return (
<VStack>
<VStack spacing={10} w="30vw">
<Spacer />
<Heading>The Password Game</Heading>
<FormControl>
<FormLabel>Password</FormLabel>
<Input
id="password"
placeholder="password"
value={password}
borderColor="black"
onChange={(e) => setPassword(e.target.value)}
/>
</FormControl>
</VStack>
</VStack>
);
};
export default Home;
useState()
によってフォームに入力されるたびにpassword
を更新しています。
2.エラーメッセージを追加してみる
ChakraUIには<FormErrorMessage>
というコンポーネントも用意されています。これは<FormContorl>
のpropsであるisInvalid
に条件式を代入することで、条件式がtrue
の場合表示させることができるものです。試しにパスワードが空(Empty)であるかを判定します。
エラーメッセージを表示させることができました。
3.複数のエラーを追加する
条件式とエラーメッセージに対応するinterfaceを作成します。
error
には「errorになる場合」の条件を書きます。
(idはkey
に当てるために使います)
interface PasswordValidator {
error: boolean;
message: string;
id: number;
}
- 8文字以上である
- 大文字を含む
の2つの条件を格納するPasswordValidator
を定義します。
(先程のisPasswordEmpty
も書き直します)
const isPasswordEmpty: PasswordValidator = {
error: password === "",
message: "パスワードを入力してください",
id: 0,
};
const hasPasswordEnoughCharacters: PasswordValidator = {
error: password.length < 8,
message: "パスワードは8文字以上である必要があります。",
id: 1,
};
const hasPasswordUppercase: PasswordValidator = {
error: /\[A-Z]/g.test(password),
message: "パスワードは大文字を含む必要があります",
id: 2,
};
const AllValidator = [
isPasswordEmpty,
hasPasswordEnoughCharacters,
hasPasswordUppercase,
];
hasPasswordUppercase
では正規表現を使って大文字判定をしています。
次に、isInvalid
に「AllValidator
のうち1つでもtrueならtrueを返す」式を入れます。
<FormControl isInvalid={AllValidator.some((e) => e.error)}>
JavaScriptのArray.prototype.some()
では全ての要素に対してフィルタリングを行い、一つでもtrueであった場合trueが返されます。これで1つでもエラーが起きた場合エラーメッセージが表示されます。
4.対応するエラーメッセージを追加する
<FormErrorMessage>
{isPasswordEmpty.message}
</FormErrorMessage>
<FormErrorMessage>
{hasPasswordEnoughCharacters.message}
</FormErrorMessage>
<FormErrorMessage>
{hasPasswordUppercase.message}
</FormErrorMessage>
先程のようにFormErrorMessage
を追加してみます。
おや...?
大文字を入力したのにエラ〜メッセージが消えていません。
当たり前です。他のエラー(この場合hasPasswordEnoughCharacters
)がtrueなのでそれに釣られてこのエラーメッセージも表示されてしまいます。なのでif文を使って対応するエラーに応じて表示/非表示を切り替えられるようにします。
{AllValidator.map((validate) => {
if (validate.error) {
return (
<FormErrorMessage>
{validate.message}
</FormErrorMessage>
);
}
})}
存在するエラーメッセージのみ表示されるようになりました。あとはPasswordValidator
を好きなだけ増やせば自分だけのThe Password Gameが作れます。
ということで条件を増やしまくりました。
Vercelにデプロイしたので遊んでみてください。ボタンは飾りです。
Discussion