ブックマーク / zenn.dev/catnose99 (23)

  • Webサービス公開前のチェックリスト

    個人的に「Webサービスの公開前チェックリスト」を作っていたのですが、けっこう育ってきたので公開します。このリストは、過去に自分がミスしたときや、情報収集する中で「明日は我が身…」と思ったときなどに個人的にメモしてきたものをまとめた内容になります。 セキュリティ 認証に関わるCookieの属性 HttpOnly属性が設定されていること XSSの緩和策 SameSite属性がLaxもしくはStrictになっていること 主にCSRF対策のため。Laxの場合、GETリクエストで更新処理を行っているエンドポイントがないか合わせて確認 Secure属性が設定されていること HTTPS通信でのみCookieが送られるように Domain属性が適切に設定されていること サブドメインにもCookieが送られる設定の場合、他のサブドメインのサイトに脆弱性があるとそこからインシデントに繋がるリスクを理解してお

    Webサービス公開前のチェックリスト
    toshikish
    toshikish 2024/07/04
  • iOSブラウザで快適に書けるエディターを作るの大変すぎ問題

    iOSのブラウザ(Safari、Chromeなどなど)で体験の良いWYSIWYGエディタを作るのは無理ゲーである。色々と理由はあるが、いちばん辛いのはバーチャルキーボード(オンスクリーンキーボード)を表示したときの挙動だと思っている。 キーボードが表示されているときにposition: fixedが効かない WYSIWYGエディタではテキストの装飾や画像挿入などのボタンを画面のどこかに固定したくなることが多い。 しかし、iOS Safariではキーボードが表示されているときにposition: fixedなどのCSSだけで画面上に何かを固定させることが難しい。 position: fixedとbottom: 0 やtop: 0を使っても要素が画面に固定されない仕様となっている(これはposition: stickyにしても同じ)。 ワークアラウンドも上手く動かない noteやscrapbo

    iOSブラウザで快適に書けるエディターを作るの大変すぎ問題
    toshikish
    toshikish 2023/12/22
  • しずかなインターネットの技術構成

    こんなWebサービスをリリースしたので、技術的な話をまとめておこうと思います。 元々このサービスは、趣味の延長線のような感じで開発を始めました。競合にあたるnoteはてなブログなどのサービスが確固たる地位を築いているということもあり、「お金にはならないだろうけど、自分の趣味を詰め込んだものにしよう」というゆるい気持ちで開発を続けています(楽しい)。 選定の方針 趣味と言っても文章投稿サービスなので、ユーザーが少数であったとしても長期間運営しなければなりません。そのため、ユーザー数が少なければランニングコストが数千円/月以下、ユーザー数が増えたときは段階的にコストが上がるように選定を行いました。 アプリケーション フルスタックNext.jsアプリケーションをCloud Runにデプロイしています。各APIエンドポイントはNext.jsAPI Routesで生やしています。 Next.js

    しずかなインターネットの技術構成
    toshikish
    toshikish 2023/11/29
  • だれでもAIメーカーの技術スタックとか

    主な使用サービス/ライブラリは以下です。 Next.js …アプリケーションのフレームワーク Vercel …デプロイ先 PlanetScale …サーバーレスDB(MySQL)。ORMにはPrismaを使用 Upstash …サーバーレスでRedisを使えるやつ Cloudflare R2 …画像のアップロード先 Open AI API ここに落ち着くまでに紆余曲折あったので、少し詳しく説明しておきます。 Next.js on Vercel 利用しているフレームワークはNext.jsです。クライアントからのデータの取得・更新リクエストはAPI Routesから受け付けるようにしています。 アプリケーションのデプロイ先はVercelにしました。最初はNext.js on Cloudflare Workersをやろうとしたのですが、辛い部分が多くて断念しました。 余談)なぜNext.jsをC

    だれでもAIメーカーの技術スタックとか
    toshikish
    toshikish 2023/05/05
  • 未ログインでも叩けるAPIエンドポイントにレートリミットを導入する

    先日だれでもAIメーカーというWebサービスをリリースしました。このサービスは例によってOpenAI APIを使っており、トークンの使用量がランニングコストに大きく影響します。 また、気軽に使ってもらえるよう未ログインでも使用できる仕様にしているため、気をつけないと悪意のある人に大量にトークンを使用されてしまう可能性があります。 ノーガードだとどうなるか 例えば、POST /api/askという「リクエストbodyのpromptの値を取り出し、OpenAI APIのChat Completionsに投げる」という単純なエンドポイントを作ったとします。 「未ログインでも使ってもらいたいから」と認証を一切しなかった場合どうなるでしょうか? 悪意のある攻撃者に見つかれば、promptを上限ギリギリの長さの文章に設定したうえで、/api/askに対してDoS攻撃するかもしれません。 トークンを大量

    未ログインでも叩けるAPIエンドポイントにレートリミットを導入する
    toshikish
    toshikish 2023/05/03
  • Webサービスで「ユーザーページに独自ドメインを登録できる」機能を提供するのがなぜ難しいか

    コンテンツ投稿系のWebサービスでは「ユーザーのページに好きな独自ドメインを登録できる」という機能をつけたくなることがあります。ユーザーからすると「コンテンツが自分自身の所有物であること」を感じやすいですし、コンテンツのポータビリティが上がりますし、とても夢がありますよね。僕もいつか実装してみたい機能のひとつです。 しかし、この機能を提供するには、以下のようなハードルがあります。 料金 ベンダーロックイン 複雑な実装(とくに認証) (1)の料金についてはデプロイ先によります。例えばVercelであればProプラン以上であれば無制限に独自ドメインを登録できます(Unlimited custom domains for all Pro teams)。 Google Cloudの場合にはCertificate Managerで独自ドメインごとの証明書を管理するのに「ひとつあたり○USD」という感

    Webサービスで「ユーザーページに独自ドメインを登録できる」機能を提供するのがなぜ難しいか
    toshikish
    toshikish 2022/10/18
  • RemixをCloudflare Workersで動かす & KVでデータをキャッシュする

    2022/12/04 追記 RemixをCloudflare Pagesで動かせるようになりました。 詳しくは Deploy a Remix siteをチェックするのがおすすめです。 前回の記事 この記事ではRemixをCloudflare Workersにデプロイしつつ、Workers KVで外部APIから取得したデータをキャッシュしてみたいと思います。 Remixをローカルで開発

    RemixをCloudflare Workersで動かす & KVでデータをキャッシュする
    toshikish
    toshikish 2021/11/26
  • Cloudflare WorkersでSSRができると何が嬉しいか

    Next.jsの対抗馬となりそうなReactのフレームワークでRemixのv1.0がリリースされました。 個人的にRemixでいちばん魅力を感じているのはCloudflare WorkersでSSRができるという点です(現状ではNext.jsCloudflare Workers上でSSRするのは難しい)。これがなぜ嬉しいのかと言うと、パフォーマンスを出しつつ、低コストで運用でき、大量のアクセスに対しても低コストでスケールできそうだからです。 そもそもSSRをする必要ある? ほとんどのWebサービスはSSRなしでSPAとしてビルドし、Cloudflare PagesやGitHub Pagesに静的ファイルをのせて動かせば十分だと思います。 例えば僕が先日作った個人開発のサービスもReact on Cloudflare Pagesの完全なSPAですが、SSRが必要な要素はまったくありません。

    Cloudflare WorkersでSSRができると何が嬉しいか
    toshikish
    toshikish 2021/11/24
  • Tailwind CSSでお手軽ローディングアニメーション

    Talewind CSSでローディング・アニメーションを表示したくなったのですが、ググってもちょうど良いサンプルが見つかりませんでした。 というわけでコピペで簡単に使えるサンプルコードをいくつか考えてみました。あまりクオリティが高いものではないですが「Tailwind CSSでとりあえず何かローディング中っぽい表示にしたい」という場合にご自由にコピペしてお使いください。 波紋が広がるアニメーション <div className="flex justify-center" aria-label="読み込み中"> <div className="animate-ping h-4 w-4 bg-blue-600 rounded-full"></div> </div> アレンジ Reactでない場合はclassNameをclassに置き換えてください(もしくはCodePenのコードをコピペ) bg

    Tailwind CSSでお手軽ローディングアニメーション
    toshikish
    toshikish 2021/11/15
  • Next.jsのmiddlewareはVercel以外でも問題なく使えるか

    Next.jsでv12〜middlewareという機能が使えるようになりました。 middlewareに書いた処理はリクエストが完了する前に実行されます。Cookieの値に応じてルーティングを振り分けたり、Basic認証を導入したり等など、幅広い用途で使えそうです。 VercelNext.jsの組み合わせが強いのは、VercelNext.jsをデプロイするとこのmiddleware部分をEdge Functionsで捌いてくれるという点です。つまり、静的なページに対するリクエストに対して、オリジンサーバーに触れことなくmiddlewareを実行できるということです。 Vercel以外のプラットフォームだとどうなのか ドキュメントには以下のような記載があります。 This works out of the box using next start, as well as on Edge

    Next.jsのmiddlewareはVercel以外でも問題なく使えるか
    toshikish
    toshikish 2021/10/28
  • ビデオ会議でカメラの映像の代わりに絵文字を配信するためのツールを作った

    ビデオ会議で顔出しNGな人でも感情を表現できるように、絵文字やテキストをカメラ映像代わりに表示するためのサービスを作りました。 自分のカメラ映像の代わりにこういうやつを表示 👆 こんな感じでZoomやGoogle Meetでのビデオ会議で、自分の顔の代わりに絵文字を表示できるサービスです。絵文字に動きをつけたり、自由に文字入力することもできます。 👆 画面共有ではなく、来自分の映像が表示されるスペースに、絵文字を表示させるような形で使います。 ユーザー登録なしで使えますが、ZoomやGoogle Meetにブラウザの画面を表示するためにOBSをインストールする必要があります。初回の設定手順は使い方ページで詳しく説明してあります。 作った理由 Zoomのイベントでパネルディスカッションに参加することになったからです(DevIO 2021)。顔は出したくないものの、自分だけ静止画のアイコ

    ビデオ会議でカメラの映像の代わりに絵文字を配信するためのツールを作った
    toshikish
    toshikish 2021/10/06
  • Cloudflare Pages・Vercel ・Netlify の違いや使い分けをまとめる

    Vercel VercelNext.jsなら特に設定しなくともSSRができる状態でデプロイできる。Nuxt.jsだとコミュニティが用意しているbuilderを使えばSSR対応アプリをVercelにデプロイできる。builderが用意されていないフレームワークでSSRを行うにはデプロイ周りで頑張る必要が出てくる。 VercelではちょっとしたWeb APIを用意したいときも、/apiディレクトリを用意してJSファイルなどを置いておけばまとめてデプロイしてくれる。 Netlify サーバーサイドで動かしたいスクリプトはNetlify Functionsで動かすことになるが、フレームワークごとに用意されているプラグインを使うことでまとめてデプロイができたりする。例えばnetlify-plugin-nextjsを使えばNext.jsでSSR対応したアプリを動かせるっぽい。またnetlify.to

    Cloudflare Pages・Vercel ・Netlify の違いや使い分けをまとめる
    toshikish
    toshikish 2021/04/14
  • Next.jsのISRで動的コンテンツをキャッシュするときの戦略

    最近Next.jsのISR(Incremental Static Regeneration)を耳にする機会が増えてきました。Zennでも2021/3/17時点で記事やなどの一部のページでISRを採用しています。 ISRとは何か ISRを使うことで、動的なコンテンツを含むページも静的ページとしてCDNにキャッシュすることが可能になります。Next.jsのISRはドキュメントに書かれているようにstale-while-revalidateという考え方でキャッシュが行われます。 具体的には、リクエスト時にページのキャッシュを作成し、次のアクセスではキャッシュされた古いデータを返します。その裏で次のアクセスに向けてキャッシュが再生成されるというイメージです。 これによりユーザー投稿コンテンツであってもCDNにキャッシュしやすくなるというわけです。 Next.jsでのISRの実装 デプロイ先がVe

    Next.jsのISRで動的コンテンツをキャッシュするときの戦略
    toshikish
    toshikish 2021/03/18
  • Zennで発生した障害の原因と行なった対策のまとめ

    2021/02/24の11時頃〜1時間ほどzenn.devにアクセスしづらい・アクセスできない問題が発生していました。その後も3時間ほど一部のページへのアクセスができない状況となっていました。Zennに投稿してくれた方、見に来てくれた方、ご迷惑をおかけしてすみませんでした。 今回の障害は学びが多かったので、個人の記事として残しておくことにします。 原因 今回の障害は、使用しているクラウドサービスではなく、Zenn自体に原因がありました。 1. KaTeX記法により生成されるHTMLが思った以上に大きかった ZennのマークダウンエディターではKaTeX記法をサポートしています。例えば、$a\ne0$と書くとa\ne0と表示されます。 KaTeXはサーバーサイドレンダリングをサポートしており、KaTeX記法からの数式のHTMLへの変換はサーバーサイドで行なっていました。DBにはマークダウンだ

    Zennで発生した障害の原因と行なった対策のまとめ
    toshikish
    toshikish 2021/02/26
  • 【Chrome】textareaの改行時にカーソル位置がガタっとずれる問題の対処法

    Enterキーを押すとtextareaのスクロール位置がずれる問題 ふとZennのスクラップのエディターで、Enterキーを押すと、カーソルのあたっている部分のスクロール位置がガタっとずれる問題が発生することに気づきました。 Enterキーを押したタイミングでカーソルの位置がviewportの先頭もしくは末尾にジャンプするようなイメージです。 もう少し調べてみると、Chromeでは問題が発生するものの、FirefoxやSafariでは問題が再現できませんでした。 とりあえずautosize textareaを疑う スクラップのエディターではtextareaの高さがテキストの長さに応じて変わるreact-textarea-autosizeを使っています。最初はこのパッケージを疑ったのですが、HTMLの<textarea>タグに書き換えても問題は解消しませんでした。 Reactのcursor

    【Chrome】textareaの改行時にカーソル位置がガタっとずれる問題の対処法
    toshikish
    toshikish 2021/02/21
  • 満足して使っている有料サービスの一覧

    こちらにリクエストがあったので整理も兼ねてまとめておく。 (技術関連以外のサービスも含めたかったのでスクラップに書くことにした) TablePlus SQLクライアント MySQL、PostgreSQ、Redis、MongoDBなどに対応 UIが良い。見やすい。操作しやすい。複数の接続先を管理しやすい ときどき「有料プランに入らない?」的なポップアップが出るので課金。これを書いてる時点ではマシン1台ごとに約$60の課金 快適なので課金してよかった

    満足して使っている有料サービスの一覧
    toshikish
    toshikish 2021/02/11
  • Next.js の InferGetStaticPropsType が便利

    Next.jsのサンプルリポジトリを眺めていたらInferGetStaticPropsTypeというものを見つけました。これを使うと、getStaticPropsでreturnされた値をもとに、Pageに渡されるPropsの型を類推してくれます。 ↓ ドキュメントはこちら これまではこんな感じで書いていた これまではPropsの型宣言を自分で書いていました。 import { GetStaticProps } from 'next'; // 👇 type Props = { posts: Post[] }; export const getStaticProps: GetStaticProps<Props> = async () => { const { posts } = await getPosts(); return { props: { posts, }, revalidate:

    Next.js の InferGetStaticPropsType が便利
    toshikish
    toshikish 2021/01/05
  • Next.jsのFont Optimizations(Webフォントの最適化)を試してみる

    追記) v10.2からデフォルトでGoogle Fontsの最適化が行われるように Next.js v10.2から自動でWebフォントの最適化が行われるようになりました。v10.2時点ではGoogle Fontsにのみ対応しているとのことです。特に設定は不要で、いつも通りGoogle Fontsを読み込めばOKです。 ↓ 詳細 これより下の解説は古い内容になります。実装の参考にしないようお願いします。 以前、Next.jsのリポジトリを眺めていたときにFont Optimizationsというプルリクエストを見つけました。 2020年12月時点ではExperimantalな機能のようですが、v10.0.4で既に使えるようになっていたので試してみました。 :::message alertz Next.js v10.0.4でのドキュメントに則っていない記録になります。 ::: Font Opt

    Next.jsのFont Optimizations(Webフォントの最適化)を試してみる
    toshikish
    toshikish 2020/12/29
  • Google App Engineのスタンダード/フレキシブル環境を選ぶときのヒントと設定の注意点

    イメージとしては スタンダード環境の方が気楽にはじめられる フレキシブル環境の方がより細かな設定ができる という感じでしょうか。 「料金が安いのはスタンダード」とは限らない ググって見つかる情報を読むと、多くの人は「スタンダード環境の方が安く済みそうだ」という印象を持つと思います。僕もそのような考えから、当然のようにスタンダード環境を選んでいました。しかし、結果として、Zennの場合にはフレキシブル環境の方が料金は大幅に安く済むことが分かりました。 Zennの場合 具体例があった方が読んでいて楽しいと思うので、恥を捨てて実際にかかっていたGAEの料金を載せてしまいます。ほれっ。 ※ 料金の推移は、サービスへのアクセス数とはほぼ相関していない ピーク時には1万円/日近くいってしまっていますが、設定と環境を見直すと¥500/日くらいで済むようになりました。設定をミスらなければPS5を転売ヤーか

    Google App Engineのスタンダード/フレキシブル環境を選ぶときのヒントと設定の注意点
    toshikish
    toshikish 2020/12/26
  • Webサービスのアクセシビリティについて 考慮すべきポイントを挙げてく

    WebサービスやWebサイトを開発するうえで最低限おさえておきたいアクセシビリティのポイントを雑多に挙げてく。ある程度のボリュームになったら記事にする予定。

    Webサービスのアクセシビリティについて 考慮すべきポイントを挙げてく
    toshikish
    toshikish 2020/11/28