eityansメモ

eityansメモ

ゆるくやっていきます

記事一覧

Next.js(Vercel) + Rails + Auth0を使ってログイン機能を作る

Next.js(Vercel)でフロントエンド、Railsでバックエンドを用意する。結構やることが多かったのでメモ。

原則は公式のドキュメントを参照

大きな流れ

なかなか全体像がつかみにくかった。今回取り組んでわかったことをまとめる。

  1. ユーザーはNextからログインや登録を行い、Auth0に遷移する。

  2. Auth0に遷移し、そこで認証を行う。認証が成功するとアクセストークンがJWTとして取得できるようになる

  3. Next側でそのJWTを使ってRailsに情報を連携する

  4. Rails側でJWTをパースし、問題なかったら処理を実行する

こういうことを行うためにこれから色々設定をする。


Auth0の設定

アプリケーションを作る

Reguler Web Applicationsを選択。アプリケーションを作ると、QuickStartでフレームワークごとの設定が案内されるので、原則そらのドキュメントに従う。

コールバックの設定

ローカル用と、本番のそれぞれを入力する。後述するSDKを用いればそのあたりのエンドポイントは勝手に作られる。

Next.js側の設定

Auth0 Next.js SDKをインストール

1npm install @auth0/nextjs-auth0

dotenvで環境変数を設定する

どう設定すれば良いのかはドキュメントに記載されてる。

SDK Clientを作る

サンプルをベースに少し改造

1// lib/auth0.js
2
3import { Auth0Client } from "@auth0/nextjs-auth0/server";
4
5export const auth0 = new Auth0Client({
6  domain: process.env.AUTH0_DOMAIN,
7  clientId: process.env.AUTH0_CLIENT_ID,
8  clientSecret: process.env.AUTH0_CLIENT_SECRET,
9  appBaseUrl: process.env.APP_BASE_URL,
10  secret: process.env.AUTH0_SECRET,
11
12  authorizationParameters: {
13    scope: process.env.AUTH0_SCOPE,
14    audience: process.env.AUTH0_AUDIENCE,
15  }
16  async onCallback(error, context, session) {ユーザー作成の処理}
17});
ここでonCallbackを設定して、認証後にユーザーの作成を実施するようにしている。

Middlewareの作成

このサンプルもドキュメントから。

1import type { NextRequest } from "next/server";
2import { auth0 } from "./lib/auth0";
3
4export async function middleware(request: NextRequest) {
5  return await auth0.middleware(request);
6}
7
8export const config = {
9  matcher: [
10    "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
11  ],
12};

ここまででログインやログアウトのエンドポイントが作られる。

ログインボタンの設置

1<a href="/auth/login">ログイン/新規登録</a>

ここでLinkなどを使うと先読みが入ってややこしくなるらしい。

Vercel側の設定

環境変数を設定する

設定した環境変数

  • AUTH0_CLIENT_ID

  • AUTH0_CLIENT_SECRET

  • AUTH0_SECRET

  • AUTH0_DOMAIN:https://を取り除かないとエラーがでる

  • AUTH0_AUDIENCE

  • AUTH0_SCOPE

  • APP_BASE_URL

最初環境変数の設定をミスっていてローカルでは問題ないのに本番でMIDDLEWARE_INVOCATION_FAILEDエラーが発生して詰まっていた。

Railsとの連携

この記事がわかりやすい。これに従って設定する。

Auth0APIの作成

Auth0のダッシュボードで作成。

Identifierと、ドメインの情報を記録する。これをRailsの設定に使う。

jwt gemの追加

1gem 'jwt'

Identifierと、ドメインの情報をクレデンシャルに追加

1EDITOR="vim" bundle exec rails credentials:edit --environment development
1auth0:  
2  api_identifier: xxx
3  domain: xxx

ここでのdomainはhttps://を含まない

JWTの検証をするクラスを作成

このあたりもドキュメントのママ

1# app/lib/json_web_token.rb
2require 'net/http'
3require 'uri'
4
5class JsonWebToken
6  def self.verify(token)
7    JWT.decode(token, nil,
8               true, # Verify the signature of this token
9               algorithm: 'RS256',
10               iss: "https://#{Rails.application.credentials.auth0[:domain]}/",
11               verify_iss: true,
12               aud: Rails.application.credentials.auth0[:api_identifier],
13               verify_aud: true) do |header|
14      jwks_hash[header['kid']]
15    end
16  end
17
18  def self.jwks_hash
19    jwks_raw = Net::HTTP.get URI("https://#{Rails.application.credentials.auth0[:domain]}/.well-known/jwks.json")
20    jwks_keys = Array(JSON.parse(jwks_raw)['keys'])
21    Hash[
22      jwks_keys
23      .map do |k|
24        [
25          k['kid'],
26          OpenSSL::X509::Certificate.new(
27            Base64.decode64(k['x5c'].first)
28          ).public_key
29        ]
30      end
31    ]
32  end
33end

認証周りのサービスクラスを作成

TokenVerificationを作り、認証してユーザーを返すAuthorizationServiceと、新規にユーザーを作成するUserRegistrationServiceを作る

1module TokenVerification
2  private
3
4  def http_token
5    if @headers["Authorization"].present?
6      @headers["Authorization"].split(" ").last
7    end
8  end
9
10  def verify_token
11    JsonWebToken.verify(http_token)
12  end
13end

1class AuthenticationService
2  include TokenVerification
3
4  def initialize(headers = {})
5    @headers = headers
6  end
7
8  def perform!
9    payload, _header = verify_token
10    User.find_by!(sub: payload["sub"])
11  end
12end

1class UserRegistrationService
2  include TokenVerification
3
4  def initialize(headers = {})
5    @headers = headers
6  end
7
8  def perform!
9    payload, _header = verify_token
10    User.find_or_create_by(sub: payload["sub"])
11  end
12end

認証用のコントローラーの作成

認証に成功したらユーザーを返す

1class SecuredController < ApplicationController
2  before_action :authorize_request
3
4  private
5
6  def authorize_request
7    @current_user = AuthenticationService.new(request.headers).perform!
8  rescue JWT::VerificationError, JWT::DecodeError
9    render json: { errors: [ "Not Authenticated" ] }, status: :unauthorized
10  end
11
12  def current_user
13    @current_user
14  end
15end

ユーザーの作成はUsersControllerに作成

1class UsersController < SecuredController
2  skip_before_action :authorize_request, only: [ :create ]
3
4  def create
5    user = UserRegistrationService.new(request.headers).perform!
6    if user.save
7      render json: user, status: :created
8    else
9      render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
10    end
11  end
12end

これでログインまわりの機能ができた

Renderのアプリからsupabaseの無料枠DBを利用する

ちょっと作りたいアプリが出来たが、データベースに課金するほどのアプリでもない。

Renderの無料枠とsupabaseの無料枠のDBを使って、インフラコストゼロでちょっとしたサービスを作る。


database.ymlの設定

1production:
2  primary: &primary_production
3    <<: *default
4    host: <%= ENV["APP_DATABASE_HOST"] %>
5    username: <%= ENV["APP_DATABASE_USER"] %>
6    password: <%= ENV["APP_DATABASE_PASSWORD"] %>

Renderの設定

環境変数を設定する。設定した項目は以下。設定値はsupabaseから閲覧できる。

  • APP_DATABASE_HOST

  • APP_DATABASE_PASSWORD:supabase登録時のパスワード

  • APP_DATABASE_USER

  • DATABASE_URL

デプロイしようとしたところNetwork is unreachable (ActiveRecord::ConnectionNotEstablished)が発生。エラーメッセージ的にIPv6で接続をしているようで、Session poolerの情報で接続を試みると成功

スクリーンショット 2025-06-19 16.09.28

無料枠で2つのプロジェクトまで作成できるので、今動かしている個人開発のデータ移行をしても良いのかも?

フルリモートが急にしんどくなった

フルリモートの会社に1年半ほど務めている。

今の会社はフルリモートの中でも究極だと思う。朝会が毎日5~10分あるだけで、それ以外は一切会議がない。全てテキストコミュニケーション。リモートワークと仕事の効率に関する話がよく出てくるが、少なくとも今の会社においてはこのスタイルは一番効率的だと考えている。

フルリモートを始めてから最初の1年ほどはフルリモート最強という気持ちでいっぱいだったし、これを今後もずっと続けていくのだと考えていた。ただ、ここ1,2ヶ月ほどで急にフルリモートがしんどくなってしまった。仕事においてはしんどさは特に感じていない。感じているのは個人の生き方としての部分。

元からフルリモートワークに対する違和感のような物があった。ありきたりだが、社会性が失われていく感覚が強かった。自分はよくこの違和感を人に伝えるときに、「老後」という表現を使っている。決して老後にネガティブな意味を持たせているわけではない。30代に似合わない時間の使い方をしているという意味で老後という言葉を選んでいる。

リモートワークでかつ裁量労働だと好きな時間に仕事ができるし、好きな時間に休憩することも出来る。横になることもよくある。ストレスがなく、すごく自由で、それはとても魅力的なことなのだが、家で一人で仕事をしたり横になったりを繰り返していると、だんだん仕事が仕事に感じられなくなる。もちろん仕事はちゃんとしているし、成果も出しているのだが、メリハリがないというか、ずっと休日を過ごしている気持ちになる。

「ずっと休日」の字面だけ見るとそれは良いことのように見えるかもしれないが、なんとも言えないしんどさがある。休みの日と普段の日の違いが薄くなり、日々の濃淡がだんだん薄くなってくる。よく聞く「会社と家を往復するだけの毎日」みたいな愚痴、あれの範囲が極端に狭くなった状態になる。

自分の活動範囲がどんどん小さくなっていくのも感じる。全ての用事が家から出発しなければならないことが原因として大きいと思う。「ちょっと気になる場所やイベントがあるけど、家から行くほどのものでもない」ようなものがいくつかある。そういうものは家にいると億劫になって諦めてしまう。これが通勤をしていると「帰りに寄ってみよう」ができる。昔はいろいろなものに顔を出すタイプの人だったが、最近はずっと家にいる気がする。ずっと家にいると不思議なもので、何か新しいことを始める気持ちもだんだん減ってくる。

今でもボルダリングは定期的に行っているし、土日は基本出かけているため、外出自体はしている。また、同棲をしているので日常的に会話はできている。しかし、ずっと家にいると「今日こんな事があったよ」みたいな出来事が特にない。事件がない。日常が全て自分の意思で起こしたものだけになり、外乱のような偶発的事象がない。これは自由とも平穏とも気楽とも呼べるが、自分からしたら退屈になってしまった。

最近子どもがほしいのかも?などと考えていたが、よくよく考えると自分は外乱がほしいだけのような気がしてきた。子育ての大変さは知人の話から強く感じている。生半可に手を出してはいけない気持ちがある。

従来の仕事や職場というものは、こういう外乱の固まりで、無意識のうちにそれらを享受していたんだなと感じる。

もちろんフルリモートを悪者にしたいわけではない。今の環境が特殊すぎるのかもしれない。もしかしたら雑談タイム的なものを組織が用意したら解決するのかもしれない。ただ、フルリモートでない環境に移るのが手っ取り早いというところが実際にある。


一年前はフルリモート最強という考え方を持っていたので、時間とともに自分の考え方が大きく変わってしまったことを実感している。こういうふうにブログに残しているのは今の考えのスナップショットを残し、将来どんな考え方に変わっているのか再確認できたら良いなという思惑がある。

ちなみに、縁もあり、7月から新しい会社で働く。今度はハイブリッドの環境。今度はどんな考え方になるのか自分でも気になる。もしかしたら「やっぱりフルリモート最強」と言っているかもしれない

Claude Codeを0.42ドルで試したメモ

Claude4からIDEサポートされたらしい。そろそろ触るタイミングが来た感じ。触る


導入

ガイドに従ってパッケージを導入
1npm install -g @anthropic-ai/claude-code

VSCode開いてClaude Codeを起動

1claude

コンソールでの差分表記のスタイルを聞かれるけど、なんでも良いのでデフォルトを選択

image

ログイン方法を選択する。定額課金かAPIの従量課金か選択する。まずはお試しなので従量課金を選んでみる。

image

クレジットを5ドル買ってねと言われる。払うぞ

image

セッティング周りは一旦デフォルトで

image

使ってみる

お題としてこのブログのヘッダーに自分のソーシャルアカウントのリンクを張りたいことを伝える。

そうすると、どういう道のりでタスクを完了する予定なのか示してくれる。Clineもそういう進め方をするけど、Claude Codeの方が見やすいかも。

どういうライブラリを使っているのかとか、そういう背景を考慮してコードを書いてくれる。

image

作業のステップごとに確認してくる。これは飛ばすことも出来るけど今は一個ずつ確認。

ほぼお任せでやりたいことができた

最終的に$0.42かかりました。

感想

あまり難しいタスクをお願いしていないので評価するのも難しいのですが、これぐらいのタスクだったらCline + Deepseekでも良いかなとも思いました。

ただこっちのほうが全体のコンテキストを理解して進めてくれる感覚がありました。Clineだと1ファイルずつ読み取りを行ったりする関係上、全体を考慮したことが苦手そうな雰囲気がある。

このあたりはこれから色々試してみようかなと思います。そのうち定額制に入るかもしれません。

インプラントの緊急手術をした

インプラントの手術を受けたメモ

前歯のインプラントの手術をした。複数回手術を行う。せっかくなので記録を残す。,,骨を足す手術(0回目),2023年の9月に実施。お値段は19万円。インプラントの基本的な流れとして、骨にインプラントを埋め込むためのボルトをいれる手術を行い、その後にインプラントをいれる手術を行う。自分の場合は骨がとても薄く、まずその骨を増やす手術から行った。,手術を行ったが結果あまり骨がくっつかず、最終的に今のお医者…

前回手術をして、経過観察中に緊急手術になったのでメモ


前回の手術から一ヶ月以上経過した。食事や飲酒も自由にできていたが、手術をしたところが少し痛み始めた。

経過観察の予定があったので、痛み始めてから4日ぐらいのタイミングで再び歯医者へ、先生曰く内部で感染を起こしている可能性があり、切除するために切開するとのこと。

歯医者のあとに飲む約束をしていたが、流石に健康を優先した。(ガチのドタキャンで申し訳ない)

手術は45分ぐらいで終わった。炎症を起こしていると麻酔が効きにくいらしく、何度も麻酔を打った。麻酔を打つと心臓が早くなる。

手術はまた寝てしまった。毎回寝る。

術後、「炎症を起こした膜を全部取った」と言われた。膜???という気持ちだったが、調べたら歯根膜という膜が歯にあるらしい。それを取ったのだろうか。

術後は少し腫れているし、結構血がでている。痛み止めを飲む。夜はそうめんを食べた。

前回の手術と比べて比較的軽い印象がある。術後の腫れも引いてきている気がする。


1日後

朝は口から血が出たが、夜には血の感じはなくなった。腫れもないし痛み止めを飲まなかった。うどんとビーフシチューを食べた。

2~6日後

案外軽く、口の中に糸があるぐらいで普段通り過ごせた。コーヒーは控えている

7日後

抜糸した。歯磨きも普通にしてよくなった。良かった。

10日後

酒を飲んだ✌('ω')✌

前のページページ 1 / 13次のページ