1
1

Twitter clone Part9 ログイン成功後のページを作成

Last updated at Posted at 2023-08-15

概要

今回は nextauthのsessionを使ってログイン後のメインページに個人情報を反映するようにします。
以下 ログイン前後の画像です。
image.png

開発環境

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を有効にする

image.png

signinした時にsessionを返すようにする

image.png

nextAuthのsessionを使ってログイン前後のブラウザの表示を確認する

ログイン前 session = null

image.png

ログイン後 session != null

image.png

console.log(session)でログイン後のsessionの値を確認

image.png

コード部分

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

image.png

React

条件付きレンダー

image.png

firebase

その他

Udemy

  1. Get the session and modify sidebar and input components

githubコミット分

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1