8. Next Auth or Auth.js and Redux - Next js

Ayush RajputAyush Rajput
2 min read
  1. Install Dependencies

npx create-next-app@latest
npx shadcn@latest init
npm install @reduxjs/toolkit react-redux

//install auth.js
npm install next-auth@beta
npx auth secret // now create .env.local where this AUTH_SECRET defined

// DO basic setup of OAuth using google or Github (let move forword with github here)
// Go to developer setting in github and get the client id and client secret and put it in .env.local
  1. Create auth.js and middleware.js

//src/auth.js
import NextAuth from "next-auth";
import Github from "next-auth/providers/github"
export const {
    handlers:{GET,POST},
    auth,
    signIn,
    signOut,
}= NextAuth({
    providers:[Github]
});

//src/middleware.js
export { auth as middleware } from "@/auth"
  1. Create Api Route

//./app/api/auth/[...nextauth]/route.js
export {GET , POST} from '@/auth'
  1. Setup Redux that store cart data

// src/store/slice/cart.js
import { createSlice } from "@reduxjs/toolkit"
const initialState= {
    cartItems:[]  // get this using useSelector: const{cartItems} = useSelector((state)=>state.cart)
}
const cartSlice = createSlice({
    name:'cart',
    initialState,
    reducers:{
        addToCart(state,action){  // update this usinf dispatch(addtocart(item))

        },
        removeFromCart(state,action){
        }
    }
})
export const {addToCart,removeFromCart} = cartSlice.actions;
export default cartSlice.reducer;

// src/store/index.js
import { configureStore } from "@reduxjs/toolkit"
import cartReducer from "@/store/slices/cart"
const store = configureStore({
    reducer:{
        cart:cartReducer
    }
})
export default store;

//src/provider/index.js
"use client"
import store from "@/store"
import { Provider } from "react-redux"
export default function ReduxProvider({children}){
    return <Provider store={store}>{children}</Provider> // this bind our next application with nextjs
}

//src/component/common-layout/index.js
import ReduxProvider from "@/provider"
async function CommonLayout({children}){
    return <ReduxProvider>{children}</ReduxProvider>
}
export default CommonLayout

//layout.js
      <body className={`${geistSans.variable} ${geistMono.variable} antialiased`} >
        <CommonLayout>{children}</CommonLayout>
      </body>
  1. OnClick Login button → auththenticate user via github(or google)

// src/actions/index.js
import { signIn, signOut } from "@/auth" 
export async function loginAction(){
    await signIn('github')
}
export async function logOutAction(){
    await signOut()
}

// in frontend 
'use client' -> // In client component we can not make our main function asycn so we have to pass our getSession as a from from previous components
 <form action={getSession?.user ? handleOauthSignOut : handleOauthSignIn}> // we use form because we call this using server actions(see above)
     <Button type='submit'> {getSession?.user ? 'Logout' : 'Login'}</Button>
  </form>
 async function handleOauthSignIn(){
    await loginAction()
  }
 async function handleOauthSignOut(){
    await logOutAction()
  }
  1. If my user is successfully authenticated then show dashboard/logout (not login button)

  // Write this code in every private page (Home / dashboard / productdetail)
  const getSession = await auth();
  console.log(getSession)

  if(!getSession?.user) redirect("/unauth-page") // this will give us all info of github(or google) user like name , email and image

// on unauth-page
if(getSession?.user) redirect("/")
0
Subscribe to my newsletter

Read articles from Ayush Rajput directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ayush Rajput
Ayush Rajput