Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWSでサーバレスな書籍管理アプリを作る

 AWSでサーバレスな書籍管理アプリを作る

Avatar for Ryosuke Uchiyama

Ryosuke Uchiyama

May 09, 2025
Tweet

More Decks by Ryosuke Uchiyama

Other Decks in Technology

Transcript

  1. アカウント作成、ログイン機能 © 2025 minato project. 10 AWS Amplify UI Componentsを活用し簡易的な実装とした

    root.render( <> <CssBaseline /> <Authenticator.Provider> <LoadingProvider> <App /> </LoadingProvider> </Authenticator.Provider> </> ) index.tsx 32 33 34 35 36 37 38 39 40 41 const Settings: React.FC = () => { const navigate = useNavigate(); const { user, signOut } = useAuthenticator((context) => [context.user]); const [disabled, setDisabled] = useState(false); ... }; Settings.tsx 17 18 19 20 ... 59
  2. なぜキャリアメールへのメールが届かないのか? © 2025 minato project. 12 結論 キャリアが送信ドメイン認証を行っていたから 送信ドメイン認証とは なりすましメールや迷惑メールへの対策として、送信元のIPアドレスとDNSサーバに公開された送信用メールサーバのIPアドレ

    スが一致しているかを確認すること。送信元のIPアドレスの確認には、メールヘッダーに含まれるFromフィールドが利用され ている。キャリアにメールを送信するにはDMARCに準拠する必要がある。 DMARCとは SPFやDKIMの認証が失敗した場合の対 応策を定めたもの。送信側は受信側の 認証失敗時の推奨アクションをDNSに 「DMARCポリシー」として宣言してお き、受信側は認証失敗時にこのDMARC ポリシーを参照して、受信メールをど う扱うか判断する。 SPFとは IPアドレスを利用して受信したメール の送信元が詐称されていないかを確認 する。メール送信時に利用するサーバ のIPアドレスを送信側のDNSに「SPF レコード」として事前に登録。受信側 はメール受信時に送信側のSPFレコー ドと照合し、なりすましかどうかを判 断する。 DKIMとは 電子署名を利用してメール送信元が詐 称されていないかを確認する。送信側 がメールに電子署名を付与し、受信側 はそれをメール受信時に検証すること で、なりすましやメールの改ざんを検 知する。
  3. バーコード読取 © 2025 minato project. 16 書籍JANコードを読み捨ててISBNだけ取るようにした const handleScan =

    useCallback(async (results: IDetectedBarcode[]) => { setIsLoadingOverlay(true); if (results.length > 0) { for (const item of results) { if (item.rawValue.startsWith("978") || item.rawValue.startsWith("979")) { ... } } } setIsLoadingOverlay(false); }, [getBooksAsync, checkExists, navigate, setIsLoadingOverlay, searchOpenBdAsync]); ReadBarcode.tsx 113 114 115 116 117 118 ... 145 146 147 148 149 150
  4. 書籍情報の取得、登録 © 2025 minato project. 17 openBDのAPIで書籍情報を取得するようにした try { await

    axios.get(url) .then(r => { console.log("response", r); if (r.data.length === 1) { response = createResponse(200, r.data[0]); } else { response = createResponse(500, { message: "検索結果が1件ではありませんでした。" }); } }); } catch (error) { console.log("error", error); response = createResponse(500, error); } search-openbd/app.mjs 32 33 34 35 36 37 38 39 40 41 42 43 44 45
  5. 書籍情報の検索、一覧取得 © 2025 minato project. 18 キーワード入力のイベント抑止 (debounce) とフィルタ対応 const

    [debouncedKeyword] = useDebounce(keyword, 500); ... const result = await getBooksAsync({ pageSize: PAGE_SIZE, lastEvaluatedKey: undefined, keyword: debouncedKeyword, sortKeyId: sortKeyId, desc: isDesc, }); Books.tsx 89 ... 174 175 176 177 178 179 180 // 取得件数がpageSizeに到達するまでQueryし続ける while (currentLength < pageSize) { ... } ... // 取得結果がpageSizeより多い場合はスライスする if (items.length > pageSize) { items = items.slice(0, pageSize); currentLastEvaluatedKey.username = userName; currentLastEvaluatedKey.seqno = items[items.length - 1].seqno; } get-books/app.mjs 84 85 ... 103 ... 105 106 107 108 109 110
  6. APIGWにCognito認証を追加する © 2025 minato project. 19 OPTIONSに認証設定を入れてはいけない(戒め) Resources: ... ApiGateway:

    Type: AWS::Serverless::Api Properties: ... Auth: DefaultAuthorizer: CognitoAuthorizer AddDefaultAuthorizerToCorsPreflight: false Authorizers: CognitoAuthorizer: UserPoolArn: arn:aws:cognito-idp:... template.yaml 22 ... 72 73 74 ... 87 88 89 90 91 92 const session = await fetchAuthSession(); const token = session?.tokens?.idToken.toString(); const options = { 'headers': { 'Content-Type': 'application/json', 'Authorization': token, }, }; TypeScript
  7. 参考資料 • QR コードスキャンライブラリ @yudiel/react-qr-scanner で IScannerComponents を設定してスキャン時の UI をカスタマイズしてみた

    | DevelopersIO • Authenticator | Amplify UI for React • 【React開発】処理待機中に画面全体を覆うオシャレなローディング画面を表示させる方法! #個人開発 - Qiita • Amazon Cognito からキャリアのアドレスにメールを送信するためにやったこと #AWS - Qiita • 送信ドメイン認証(SPF / DKIM / DMARC)の仕組みと、なりすましメール対策への活用法を徹底解説 – エン タープライズIT [COLUMNS] • API GatewayのOPTIONSメソッド(CORS)でAPIキーを不要にする(AWS SAM) | DevelopersIO © 2025 minato project. 21