概要
今回は nextauthのsessionを使ってログイン後のメインページに個人情報を反映するようにします。
以下 ログイン前後の画像です。
開発環境
OS:Windows10
IDE:VSCode
package.json
{
"name": "",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@heroicons/react": "^1.0.6",
"next": "12.0.9",
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"@types/node": "^20.4.2",
"@types/react": "^18.2.15",
"autoprefixer": "^10.4.2",
"eslint": "8.8.0",
"eslint-config-next": "12.0.9",
"postcss": "^8.4.5",
"tailwindcss": "^3.0.18"
}
}
実装のポイント
page/auth.js でnext authのsessionを有効にする
signinした時にsessionを返すようにする
nextAuthのsessionを使ってログイン前後のブラウザの表示を確認する
ログイン前 session = null
ログイン後 session != null
console.log(session)でログイン後のsessionの値を確認
コード部分
Input
Input.jsx
import {EmojiHappyIcon, PhotographIcon} from '@heroicons/react/outline';
+ import {useSession, signOut} from "next-auth/react";
export default function Input(){
+ const {data: session} = useSession();
console.log(session);
return(
<>
+ {session && (
<div className="flex border-b border-gray-200 p-3 space-x-3">
<img
onClick={signOut}
src={session.user.image}
alt="user-img"
className="h-11 w-11 rounded-full cursor-pointer hover:brightness-95"
/>
<div className="w-full dived-y devide-gray-200">
<div className="">
<textarea className="w-full border-none focus:ring-0 text-lg placeholder-gray-700">
What`s happening?`
</textarea>
</div>
<div className="flex items-center justify-between pt-2.5">
<div className="flex" >
<PhotographIcon className="h-10 w-10 hoverEffect p-2 text-sky-500 hover:bg-sky-100" />
<EmojiHappyIcon className="h-10 w-10 hoverEffect p-2 text-sky-500 hover:bg-sky-100" />
</div>
<button className="bg-blue-400 text-white px-4 py-1.5 rounded-full font-bold">Tweet</button>
</div>
</div>
</div>
)}
</>
)
}
Sidebar
Sidebar.jsx
import Image from "next/image";
import{HomeIcon} from "@heroicons/react/solid";
import{BellIcon,ClipboardIcon,DotsCircleHorizontalIcon,DotsHorizontalIcon,HashtagIcon,InboxIcon,UserIcon,BookmarkIcon} from "@heroicons/react/outline";
import SidebarMenuItem from "./SidebarMenuItem";
+ import {useSession, signIn, signOut} from "next-auth/react";
export default function Sidebar(){
+ const {data:session} = useSession();
return(
<div className="hidden sm:flex flex-col p-2 xl:items-start fixed h-full xl:ml-24">
{/* ツイッター ロゴ */}
<div className="hoverEffect p-0 hover:bg-blue-100 xl:px-1">
<Image
width="50"
height="50"
src="https://help.twitter.com/content/dam/help-twitter/brand/logo.png"
></Image>
</div>
{/* メニュー */}
<div className="mt-4 mb-2.5 xl:items-start">
<SidebarMenuItem text="Home" Icon={HomeIcon} active/>
<SidebarMenuItem text="Explore" Icon={HashtagIcon} />
+ {session && (
+ <>
<SidebarMenuItem text="Notifications" Icon={BellIcon} />
<SidebarMenuItem text="Messages" Icon={InboxIcon} />
<SidebarMenuItem text="Bookmarks" Icon={BookmarkIcon} />
<SidebarMenuItem text="Lists" Icon={ClipboardIcon} />
<SidebarMenuItem text="Profile" Icon={UserIcon} />
<SidebarMenuItem text="More" Icon={DotsCircleHorizontalIcon} />
+ </>
+ )}
</div>
{/* ボタン */}
+ {session ? (
+ <>
+ <button className="bg-blue-400 text-white rounded-full w-56 h-12 font-bold shadow-md hover::brightness-95 text-lg hidden xl:inline">Tweet</button>
{/* ミニプロファイル */}
<div>
<img
src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/profile-images/1655538932"
alt="user-img"
className="h-10 w-10 rounded-full xl:mr-2"
/>
<div className="loading-5 hidden xl:inline">
<h4 className="font-bold">RYA234</h4>
<p className="text-gray-500">@RYA234</p>
</div>
<DotsHorizontalIcon className="h-5 xl:ml-8 hidden xl:inline"/>
</div>
+ </>
+ ):(
+ <button
+ onClick={signIn}
+ className="bg-blue-400 text-white rounded-white rounded-full w-36">
+ Sign in
+ </button>
+ )}
</div>
)
}
_app
_app.jsx
import '../styles/globals.css'
import {SessionProvider} from "next-auth/react";
- function MyApp({ Component, pageProps }) {
- return <Component {...pageProps} />
+ function MyApp({ Component, pageProps:{session,...pageProps} }) {
+ return (
+ <SessionProvider session={session}>
+ <Component {...pageProps} />
+ </SessionProvider>
+ )
}
export default MyApp
api/auth
[...nextauth].jsx
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
export default NextAuth({
providers:[
GoogleProvider({
clientId:process.env.GOOGLE_CLIENT_ID,
clientSecret:process.env.GOOGLE_CLIENT_SECRET,
}),
],
pages:{
signin: "/auth/signin"
},
//
+ callbacks:{
+ async session({session, token}){
+ session.user.username = session.user.name
+ .split(" ")
+ .join("")
+ .toLocaleLowerCase();
+ session.user.uid = token.sub;
+ return session;
+ }
}
})
参考
css
javascript
Next.js
Next auth session
document client work
github _app.tsx
github pages/api/auth/[...nextauth].js
Callbacks-session
React
条件付きレンダー
firebase
その他
Udemy
- Get the session and modify sidebar and input components
githubコミット分