Background
Break News
How to add local font to Tailwind Css and NextJS? - Tutorial Design Pattern? - Blockchain Technology, How to create own Bitcoin virtual currency - Zustand mordern management state - Design Pattern - Flyweight Pattern? - Docker Full training Topic

[Project Day 7] Full Tutorial "TodoList Apps with NextJS" Zustand Axios TailwindCSS React NestJS Mongoose JWT - Next Auth guideline

Tuesday, 21 February 2023
|
Read: Completed in minutes

[Project Day 7] Full Tutorial "TodoList Apps with NextJS" Zustand Axios TailwindCSS React NestJS Mongoose JWT - Next Auth guideline

Hello everyone, welcome to Webzone tech tips I am Zidane, (my nickname: ιΈ‘θ›‹)

Good day to you. This series will share with you how to build a web application with server, client side, and you will learn many useful things on this project. 

As the title you will learn how to

- Use NestJs build a server connect with a MongoDB (use JWT for authentication, how to query on server, create schema, entity, controller, service)

- Use NextJS build a client side with TailwindCss fast build component, Zustand state management (easy manage state), Axios Request API.

After check all this full series, I believe you will have a mindset how to build a website app from backend to frontend. You will understand how to become a full stack developer through this todo web app

[Project Day 7] Full Tutorial TodoList Apps with NextJS Zustand Axios TailwindCSS React NestJS Mongoose JWT - Next Auth guideline

On day 7: We will focus on client side - how to work with authenticaiton with NextJS. we will use Next/Auth components for do it.

Full Tutorial TodoList Apps with NextJS Zustand Axios TailwindCSS React NestJS Mongoose JWT - Next Auth guideline

 

If you not yet check first articles, you can check here:

Day 1: Setup NestJS project structure and connect mongoDB πŸ‘‰ link here

Day 2: Setup CURD for NestJS πŸ‘‰ link here

Day 3: Working with JWT on NestJS πŸ‘‰ link here

Day 4: Working on Mongoose Pagination QueryπŸ‘‰ link here 

Day 5: Understand how to use @Body, @Param, @Query - postman πŸ‘‰ link here

Day 6: Understand how to implement a component, eg: Implement Toast message Component πŸ‘‰ link here

Day 7: today will learn about Next Auth for apply auth on social network, username, password πŸ‘‰ link here

πŸ‘‰ Tiktok

πŸ‘‰ Facebook:

 

 

 

 

OK let's start now

First we need to define a credentials for auth/next in

pages/api/auth/...nextauth.tsx

 

if use social network login we need to define: GoogleProvider / FacebookProvider as below template

as below source code I am using loginMember API call from NestJS server (day 1, day 2)

import NextAuth from "next-auth";
 import FacebookProvider from "next-auth/providers/facebook";
 import GoogleProvider from "next-auth/providers/google";
 import CredentialsProvider from "next-auth/providers/credentials";
 import { loginMember } from "../api.member";
 
 export default NextAuth({
   providers: [
      
     CredentialsProvider({
       id: "credentials",
       name: "TodoList Account",
       credentials: {
         username: { label: "username", type: "text" },        
         password: { label: "Password", type: "password" },
       },
       async authorize(credentials, req) {
         const response = await loginMember(    
           credentials.username,
           credentials.password
         );
  
         if (response?.statusCode === 200) {   // get result from server
           return Promise.resolve(response.params);   
 
         } else {   
           throw new Error(
             JSON.stringify({ message: response, status: false })
           );
         }
       },
     }),
   ],
   pages: {
     signIn: "/auth/login",
   },
   session: {
     strategy: "jwt",
     maxAge: 30 * 24 * 60 * 60, // 30 days
   },
   secret: process.env.SECRET || "secret_key_here",
   callbacks: {
     async signIn({ user, account, profile }) {
       if (account.provider !== "credentials") { 
       }
       return true;  
  
     },
     async jwt({ token, user, account, profile, isNewUser }) {
     
       if (account) {
         token.accessToken = user;   // save token from server  
       }
       return Promise.resolve(token);
     },
     async session({ session, token } : any) {   
       session.accessToken = token.accessToken;        
       return Promise.resolve(session);
     },
   },
 });     
 

So we need a loginMember function, we store this at

pages/api/api.member.ts 

Above code we will call a AxiosClient

import { AxiosError } from 'axios';
 import axiosClient from '../../utils/axiosClient';
 import { envConfig } from './../../utils/config'; 
  
 export const loginMember = async(
     username: string,
     password: string
 ) => {
     let url = `${envConfig.API_PATH}/users/login`
     console.log("url: ", url)
 
     try {
         const response = await axiosClient({
             method: "POST",
             url, 
             data: {
                 username, password
             }
         })
 
         const data = response.data;
         return data;
 
     } catch (error: any) { 
         return error.message
     }
 }       
 

Here is define AxiosClient detail code 

ultis/AxiosClient.tsx

import axios, { AxiosRequestConfig, AxiosResponse } from "axios"
 import { envConfig, sitePrefix } from "./config"
 
 const headers = {
     "Content-Type": "application/json"
 }
 
 const axiosClient = axios.create({
     baseURL: envConfig.API_PATH,
     withCredentials: false,
     headers
 })
 
 // before send to server
 axiosClient.interceptors.request.use(
     (config: AxiosRequestConfig) : any  => { 
         return config; 
     },
     (err) => {
         return Promise.reject(err)
     }
 )
 
 // add a response interceptor
 axiosClient.interceptors.response.use(
     function (response: AxiosResponse) {
         const msg = response?.data?.message;
         const code = response?.data?.code;
 
         if (code === 401) {
             let key = sitePrefix + "token"
             window.localStorage.setItem(key, "")
             window.sessionStorage.setItem(key, "")
             window.location.href = window.location.origin;            
         }
 
         return response
     },
     function (error) {
         if (error.response && error.response.data) {
             return Promise.reject(error.response.data)
         }
 
         return Promise.reject(error.message)
     },
 )
 
 export default axiosClient
 
 

and envConfig from ultis/config.tsx

         
                     interface IEnvConfig {
     DEVELOPMENT: {},
     STAGING: {},
     PRODUCTION: {}
 }
 
 const configEnv: IEnvConfig = {
     DEVELOPMENT: {
         API_PATH: "https://localhost:8000",
     },
 
     STAGING: {
         API_PATH: "https://localhost:8001",
     },
 
     PRODUCTION: {
 
     }
 }
 
 const env = process.env.REACT_APP_ENV || "DEVELOPMENT"
 
 export const sitePrefix = "todo_";
 export const envConfig = configEnv[env];
 
 console.log(envConfig)
        
 

pages/auth/login.tsx, on this file we need import

import { signIn } from "next-auth/react";
 
 signIn("credentials", {
           redirect: false,
           username: values["username"],
           password: values["password"],
         })
           .then((result) => {  
 
             if (!result.error) {
               setMessage({
                 isError: false,
                 msg: "Success",
               });
             } else { 
 
               let rel = JSON.parse(result.error);
               setMessage({
                 isError: true,
                 msg: rel?.message,
               });
             }
           })
           .catch((error) => console.log(error));
       }}
        
 

After that, don't forgot to update pages/_app.tsx with below content

import '../styles/globals.css'
 import '../styles/style.css'
 import type { AppProps } from 'next/app'
 import type { NextComponentType  } from 'next' //Import Component type
 
 //Add custom appProp type then use union to add it
 type CustomAppProps = AppProps & {
   Component: NextComponentType & {auth?: boolean} // add auth type fo fix 
 // build
 }
 
 import { SessionProvider, signIn, useSession  } from 'next-auth/react'
 import { useEffect } from 'react'
 
 function MyApp({ 
   Component, 
   pageProps: { session,  ...pageProps },
   router,
 
 }: CustomAppProps) {
   return (
     <SessionProvider session={ session }>
       { Component.auth ? (
           <Auth>
             <Component {...pageProps} />   
           </Auth>
         )  : (
           <Component {...pageProps} />   
         )
       
       }
       
     </SessionProvider>
   )
 }
 
 function Auth({ children }: any) {
   const { data: session, status } = useSession()
   const isUser = !!session?.user;
 
   useEffect(() => {
     if (status === "loading") return;
     if (!isUser) signIn();
   }, [isUser, status])
 
   if (isUser) {
     return children
   }
 
   return <div></div>
 }
 
 export default MyApp
        
 
Congratulation, you had config and make you app can use Next Auth Component.
See you on day 8πŸ’—
Thanks for reading. Any feedback and questions about [Project] Full Tutorial Todo web app with NextJS Zustand Axios TailwindCSS React NestJS Mongoose JWT (Day 7) - for Next Auth Component. Leave your comment on below post, we can discuss about it.
✋✋✋✋ Webzone tech Tips - I am Zidane, See you next time ✋✋✋✋



 

 





πŸ™‡πŸΌπŸ™‡πŸΌ We Appreciate Your Comments and Suggestions - Webzone, all things Tech Tips web development
Popular Webzone Tech Tips topic maybe you will be like it - by Webzone Tech Tips - Zidane
As a student, I found Blogspot very useful when I joined in 2014. I have been a developer for years . To give back and share what I learned, I started Webzone, a blog with tech tips. You can also search for tech tips zidane on Google and find my helpful posts. Love you all,

I am glad you visited my blog. I hope you find it useful for learning tech tips and webzone tricks. If you have any technical issues, feel free to browse my posts and see if they can help you solve them. You can also leave a comment or contact me if you need more assistance. Here is my blog address: https://learn-tech-tips.blogspot.com.

My blog where I share my passion for web development, webzone design, and tech tips. You will find tutorials on how to build websites from scratch, using hot trends frameworks like nestjs, nextjs, cakephp, devops, docker, and more. You will also learn how to fix common bugs on development, like a mini stackoverflow. Plus, you will discover how to easily learn programming languages such as PHP (CAKEPHP, LARAVEL), C#, C++, Web(HTML, CSS, javascript), and other useful things like Office (Excel, Photoshop). I hope you enjoy my blog and find it helpful for your projects. :)

Thanks and Best Regards!
Follow me on Tiktok @learntechtips and send me a direct message. I will be happy to chat with you.
Webzone - Zidane (huuvi168@gmail.com)
I'm developer, I like code, I like to learn new technology and want to be friend with people for learn each other
I'm a developer who loves coding, learning new technologies, and making friends with people who share the same passion. I have been a full stack developer since 2015, with more than years of experience in web development.
Copyright @2022(November) Version 1.0.0 - By Webzone, all things Tech Tips for Web Development Zidane
https://learn-tech-tips.blogspot.com