Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
T3 Stack(応用編: Next Auth & SSRの実装紹介)
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Yohei Iino
February 23, 2024
Technology
410
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
T3 Stack(応用編: Next Auth & SSRの実装紹介)
Yohei Iino
February 23, 2024
More Decks by Yohei Iino
See All by Yohei Iino
1年半放置したExpo製アプリを最新化してみた
wheatandcat
0
110
作成中のFlutterアプリの中間発表
wheatandcat
0
93
最近読んだ技術書を簡単紹介
wheatandcat
0
120
ユニバーサルリンク/アプリリンクを使ってQRコードでゲストログインできるようにする
wheatandcat
0
390
Firebase App Checkを実装したので紹介
wheatandcat
0
330
PlanetScaleの無料プランがなくなるので、NeonとTiDBを試してみた
wheatandcat
0
430
Flutter HooksとRiverpodの解説
wheatandcat
0
590
App Routerの紹介
wheatandcat
0
160
Flutter × GraphQLでアプリを作ってみる
wheatandcat
0
350
Other Decks in Technology
See All in Technology
Software Supply Chain Attackからクラウド環境を守るためにできること
lhazy
2
290
カートの信頼性を担保するWireMockを使ったe2eテスト
ykagano
0
620
What's new in Go 1.27?
ciarana
0
280
強化学習「理論」入門
enakai00
3
3.6k
Android skills に学ぶ
kokiko
0
130
FDEの心得
noriakioji
5
6.4k
2027年のMetricKit
kantacky
0
130
【書籍出版記念】 10周回って、エージェント開発は RAGがすべてだった。〜RAGの歴史と開発現場で見えた実践知〜
akiratameto
3
410
LanceDB入門
mocobeta
9
630
도구에서 동료까지: 10년차 AI 스타트업의 AI 적응기
inureyes
PRO
1
290
長期運営で肥大化したExcelマスターデータの解消に向けた移行事例
gree_tech
PRO
0
100
AI時代のアウトプット――変わったこと、変わらないこと / Devsumi 2026 Kansai #devsumi
jnchito
0
320
Featured
See All Featured
Abbi's Birthday
coloredviolet
3
9.4k
Agile that works and the tools we love
rasmusluckow
331
22k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
370
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
570
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
Writing Fast Ruby
sferik
630
63k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
470
Balancing Empowerment & Direction
lara
6
1.2k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
390
BBQ
matthewcrist
89
10k
Transcript
T3 Stack 応用編: Next Auth & SSRの実装紹介 Press Space for
next page
自己紹介 📝 飯野陽平(wheatandcat) 🏢 法人設立(合同会社UNICORN 代表社員) 💻 Work: シェアフル株式会社CTO 📚
Blog: https://www.wheatandcat.me/ 🛠 今までに作ったもの memoir ペペロミア MarkyLinky
T3 Stackとは? 最近、話題の Web アプリ開発のアーキテクチャ 以下の 3 つの思想に集点を当てて設計された技術スタック simplicity(簡潔さ) modularity(モジュール性)
full-stack typesafety(フルスタックの型安全) t3-appとしてコマンドラインツールも公開されている 全体の紹介は以前スライドを作成したので、そちらを参照 T3 Stack + Supabaseでアプリを作ってみる - Speaker Deck このスライドでは、T3 Stackの応用編として、Next AuthとSSR対応を紹介
Next Authとは? Next.jsアプリケーション専用に設計されたオープンソースの認証ライブラリ SSRや、React Server Components等のサーバーサイドでも認証が可能 様々な認証プロバイダーをサポート(Google、Facebookなど) 簡単な設定で認証が実装可能
Next Authで認証を実装 Google | NextAuth.js 各プロバイダーの設定は以下のように行う export const authOptions: NextAuthOptions
= { providers: [ DiscordProvider({ clientId: env.DISCORD_CLIENT_ID, clientSecret: env.DISCORD_CLIENT_SECRET, }), AppleProvider({ clientId: env.APPLE_ID, clientSecret: env.APPLE_SECRET, }), GoogleProvider({ clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET, }), ],
Next Authで認証を実装 Google | NextAuth.js 各プロバイダーの設定は以下のように行う DiscordProvider({ clientId: env.DISCORD_CLIENT_ID, clientSecret:
env.DISCORD_CLIENT_SECRET, }), export const authOptions: NextAuthOptions = { providers: [ AppleProvider({ clientId: env.APPLE_ID, clientSecret: env.APPLE_SECRET, }), GoogleProvider({ clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET, }), ],
Next Authで認証を実装 Google | NextAuth.js 各プロバイダーの設定は以下のように行う AppleProvider({ clientId: env.APPLE_ID, clientSecret:
env.APPLE_SECRET, }), export const authOptions: NextAuthOptions = { providers: [ DiscordProvider({ clientId: env.DISCORD_CLIENT_ID, clientSecret: env.DISCORD_CLIENT_SECRET, }), GoogleProvider({ clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET, }), ],
Next Authで認証を実装 Google | NextAuth.js 各プロバイダーの設定は以下のように行う export const authOptions: NextAuthOptions
= { providers: [ DiscordProvider({ clientId: env.DISCORD_CLIENT_ID, clientSecret: env.DISCORD_CLIENT_SECRET, }), AppleProvider({ clientId: env.APPLE_ID, clientSecret: env.APPLE_SECRET, }), GoogleProvider({ clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET, }), ],
ログイン画面の実装 プロバイダーの設定が完了したら、signInのメソッドをコールするだけで以下の画面 import { signIn, signOut, useSession } from "next-auth/react";
<button onClick={() => signIn("credentials", {callbackUrl: "/",})}> ログイン </button>
ログイン画面のカスタマイズ ログイン画面をカスタマイズしたい場合は以下を追加することで可能 export const authOptions: NextAuthOptions = { pages: {
signIn: "/auth/signin", error: "/auth/signin", },
認証実装①(クライアントサイドで取得) 認証したユーザーの値は以下で取得可能 import { signIn } from "next-auth/react"; function Home()
{ const { data: session } = useSession(); if (!session) { return (<div> ログイン前です</div>) } return ( <div> <div> ログイン後です</div> <div>{session.user.id}</div> <div>{session.user.name}</div> <div>{session.user.email}</div> </div> ) }
認証実装①(クライアントサイドで取得) 認証したユーザーの値は以下で取得可能 import { signIn } from "next-auth/react"; const {
data: session } = useSession(); function Home() { if (!session) { return (<div> ログイン前です</div>) } return ( <div> <div> ログイン後です</div> <div>{session.user.id}</div> <div>{session.user.name}</div> <div>{session.user.email}</div> </div> ) }
認証実装①(クライアントサイドで取得) 認証したユーザーの値は以下で取得可能 if (!session) { return (<div> ログイン前です</div>) } import
{ signIn } from "next-auth/react"; function Home() { const { data: session } = useSession(); return ( <div> <div> ログイン後です</div> <div>{session.user.id}</div> <div>{session.user.name}</div> <div>{session.user.email}</div> </div> ) }
認証実装①(クライアントサイドで取得) 認証したユーザーの値は以下で取得可能 <div> ログイン後です</div> <div>{session.user.id}</div> <div>{session.user.name}</div> <div>{session.user.email}</div> import { signIn
} from "next-auth/react"; function Home() { const { data: session } = useSession(); if (!session) { return (<div> ログイン前です</div>) } return ( <div> </div> ) }
認証実装①(クライアントサイドで取得) 認証したユーザーの値は以下で取得可能 import { signIn } from "next-auth/react"; function Home()
{ const { data: session } = useSession(); if (!session) { return (<div> ログイン前です</div>) } return ( <div> <div> ログイン後です</div> <div>{session.user.id}</div> <div>{session.user.name}</div> <div>{session.user.email}</div> </div> ) }
認証実装②(SSRで認証) SSRで認証したい場合は以下のように実装 import { signIn } from "next-auth/react"; import {
type GetServerSideProps } from "next"; import { getServerAuthSession } from "~/server/auth"; export const getServerSideProps: GetServerSideProps = async (ctx) => { const session = await getServerAuthSession(ctx); return { props: { session }, }; }; function Home() { const { data: session } = useSession();
認証実装②(SSRで認証) SSRで認証したい場合は以下のように実装 export const getServerSideProps: GetServerSideProps = async (ctx) =>
{ const session = await getServerAuthSession(ctx); return { props: { session }, }; }; import { signIn } from "next-auth/react"; import { type GetServerSideProps } from "next"; import { getServerAuthSession } from "~/server/auth"; function Home() { const { data: session } = useSession();
認証実装②(SSRで認証) SSRで認証したい場合は以下のように実装 const { data: session } = useSession(); import
{ signIn } from "next-auth/react"; import { type GetServerSideProps } from "next"; import { getServerAuthSession } from "~/server/auth"; export const getServerSideProps: GetServerSideProps = async (ctx) => { const session = await getServerAuthSession(ctx); return { props: { session }, }; }; function Home() {
認証実装②(SSRで認証) SSRで認証したい場合は以下のように実装 import { signIn } from "next-auth/react"; import {
type GetServerSideProps } from "next"; import { getServerAuthSession } from "~/server/auth"; export const getServerSideProps: GetServerSideProps = async (ctx) => { const session = await getServerAuthSession(ctx); return { props: { session }, }; }; function Home() { const { data: session } = useSession();
認証実装③(RSCで認証) RSCで認証したい場合は以下のように実装 現状はこれが最速の認証方法 import { getServerSession } from "next-auth/next" import
{ authOptions } from "~/server/auth"; export default async function Home() { const session = await getServerSession(authOptions)
認証実装③(RSCで認証) RSCで認証したい場合は以下のように実装 現状はこれが最速の認証方法 export default async function Home() { const
session = await getServerSession(authOptions) import { getServerSession } from "next-auth/next" import { authOptions } from "~/server/auth";
認証実装③(RSCで認証) RSCで認証したい場合は以下のように実装 現状はこれが最速の認証方法 import { getServerSession } from "next-auth/next" import
{ authOptions } from "~/server/auth"; export default async function Home() { const session = await getServerSession(authOptions)
tRPCでSSRを実装① T3 StackではtRPCでデータ取得を行っている SSRに対応するには、以下のoptionをtrueにするだけでOK 👌 import { createTRPCNext } from
"@trpc/next"; export const api = createTRPCNext<AppRouter>({ /** * Whether tRPC should await queries when server rendering pages. * * @see https://trpc.io/docs/nextjs#ssr-boolean-default-false */ ssr: true,
tRPCでSSRを実装① T3 StackではtRPCでデータ取得を行っている SSRに対応するには、以下のoptionをtrueにするだけでOK 👌 ssr: true, import { createTRPCNext
} from "@trpc/next"; export const api = createTRPCNext<AppRouter>({ /** * Whether tRPC should await queries when server rendering pages. * * @see https://trpc.io/docs/nextjs#ssr-boolean-default-false */
tRPCでSSRを実装② Server-Side Rendering | tRPC ssr:trueにするとtRPCでアクセスしている箇所をサーバーサイドでprefetchする挙動になる 以下のようなコードを実行した場合、クライアントサイドではキャッシュから取得するの動作になる function Schedule() {
const router = useRouter(); const { id } = router.query; const schedules = api.schedule.fetch.useQuery({ urlId: String(id) });
tRPCでSSRを実装② Server-Side Rendering | tRPC ssr:trueにするとtRPCでアクセスしている箇所をサーバーサイドでprefetchする挙動になる 以下のようなコードを実行した場合、クライアントサイドではキャッシュから取得するの動作になる const schedules =
api.schedule.fetch.useQuery({ urlId: String(id) }); function Schedule() { const router = useRouter(); const { id } = router.query;
tRPCでSSRを実装② Server-Side Rendering | tRPC ssr:trueにするとtRPCでアクセスしている箇所をサーバーサイドでprefetchする挙動になる 以下のようなコードを実行した場合、クライアントサイドではキャッシュから取得するの動作になる function Schedule() {
const router = useRouter(); const { id } = router.query; const schedules = api.schedule.fetch.useQuery({ urlId: String(id) });
補足: スライドで参照している開発物の紹介 Repository OOMAKA サービスURL OOMAKA | 年間スケジュール、まとめるなら SSRしている画面を軽くDEMO
まとめ T3 Stackを使うとSSR周りは、かなり楽 getServerSidePropsでゴニョゴニョする必要がなくなって開発が捗る Next Authは現状はNext.js専用だが、今後のロードマップで名前をAuthに変更して別フレームワークでも使 用可能になる予定
ご清聴ありがとうございました 🎉