1.3.13 • Published 9 months ago

easynextauth v1.3.13

Weekly downloads
-
License
GPL-3.0
Repository
github
Last release
9 months ago

Easy Next Auth

Easily Manage Authentication In Your Next.js Apps

Client

Auth Provider Component

first, we import the AuthProvider Component and wrap the main layout with the component

return (
  <AuthProivder >
	  <html  lang='en'>
			<body  className={inter.className}>{children}</body>
		</html>
  <AuthProivder/>
)

The AuthorizeClient Function

on your login or register page import AuthorizeClient Function and pass fromData to validate and pass an API route you define to handle login or register the response should contain only the session object

<form
	onSubmit={async (e) => {
		e.preventDefault();
		let form: FormData = new FormData(e.currentTarget);
		await AuthroizeCLiet( 'login'  ,form )
  }}
>

GetUser Function

To consume the User Data in your client import the GetUser Function anywhere in your app if the client isn't authorized it will return undefined otherwise, it will return the User Data it can also use to protect client routes

export default function ProtectedRoute (){
	let data = GetUser();
	if(!data) return router.replace('/login')
	return <div>{data.username}</data>
}

Server

Secret

first, in .env file, we create AUTH_SECRET key with any value that can be used as a secret

AUTH_SECRET=as2?<>KJ34@#odp349582@#1qwe

API Routes Folder Structure

first create in your API folder a folder named easyauth, inside this folder we will add routes to handle auth logic, for login you create a folder named login and for register the same thing for providers create a folder with the same name as the provider ex gitHub folder for github provider all these routes should be POST routes expect the "me" route should be GET

/api
	/easyauth
		/login
		/register
		/me
		/github

Authenticate Function

In your login or register, provider route after validating the form or saving the user in the database it's time to generate a token call the Authenticate function and pass a date (the date format should be :"10d","10h","10m" ends with d for days, h for hours, and m for minutes) and a payload the payload should be an object, the response should only return the object generated by the Authenticate function

Example

import { NextResponse } from "next/server";
import Joi, { Schema } from "joi";
import hashing from "bcrypt";
import { db } from "@/db/db";
import { Artists } from "@/db/schema";
import { eq } from "drizzle-orm";
import Authenticate from "easynextauth

export async function POST(req: Request) {
	let form = await req.formData();
	let email = form.get("email")
	let password = form.get("password")

	const schema: Schema = Joi.object({
		email: Joi.string()
		.email({ tlds: { allow: false } })
		.required()
		.min(8)
		.max(120)
		.label("Email"),
		password: Joi.string().required().min(8).max(120).label("Password"),
    });

	const { error } = schema.validate({email,password});
	if (error) return new Response(error.message, { status: 400 });

	try {
		let artist = await db
		select({
			d: Artists.id,
			email: Artists.email,
			password: Artists.password,
		})
      .from(Artists)
      .where(eq(Artists.email, data.email));

	if (artist.length === 0) {
		return new Response("Email Doesn't Exist", { status: 400 });
	}

	let hashed_pass: boolean = await hashing.compare(
		data.password,
		artist[0].password!
	);

	if (!hashed_pass) {
		return new Response("Invalid Password", { status: 400 });
	}

	let session = await Authenticate({id:artist[0].id!},"10d");

	// the response should be in json and return the session object
	return NextResponse.json(session, { status: 200 });

	} catch (error) {
		return new Response("Something Wrong Happen", { status: 400 });
	}
}

Protect Routes

To protect routes in your middleware file import the GetPayload Function the function returns the payload if the token you provide is a valid token otherwise it returns an error

Example

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import GetPayload from "easynextauth";

export async function middleware(request: NextRequest) {
  try {
    await GetPayload();
    return NextResponse.next();
  } catch (error) {
    return new Response("Invalid Token", { status: 400 });
  }
}

export const config = {
  matcher: [
    "/api/me",
    "/api/follow/:path*",
    "/api/unfollow/:path*",
    "/api/like/:path*",
    "/api/dislike/:path*",
    "/api/comment/:path*",
    "/api/upload",
  ],
};

me Route

to retrieve personal data define a route called 'me' The route should return the data you want the client to consume you can protect this route from the middleware or call the GetPayload if it throws an error response to the client with the error else it will return the payload and that's what we want I added the user id to the payload so we can use this id to retrieve user data or do other operation make sure its GET method

Example

import { NextResponse } from "next/server";
import { db } from "@/db/db";
import { Artists } from "@/db/schema";
import { eq } from "drizzle-orm";
import GetPayload from "easynextauth"

export async function GET(req: Request) {

  try {
    let payload = await GetPayload();
    let result = await db
      .select({
        id: Artists.id,
        name: Artists.name,
        followers: Artists.followers,
        following: Artists.following,
        songs: Artists.songs,
        cover: Artists.cover,
      })
      .from(Artists)
      .where(eq(Artists.id, payload.id));

    if (result.length === 0) return new Response("Something Wrong Happen", {
		status:400}

    return NextResponse.json(result[0]);

  } catch (error) {
    return new Response("Something Wrong Happen", { status: 400 });
  }
}

Providers

Github

in you easyauth api folder define a route caled github in this route call the GithubServer function and pass the client_id and the client_secret, this function will return the user personal information from github you can do whatever you want with this date

Example

import { NextResponse } from "next/server";
import { db } from "@/db/db";
import { Users } from "@/db/schema";
import GithubServer from "easynextauth"

export async function POST(req: Request) {

	let userData = await GithubServer(client_id, client_secret)

	try {
		let user = await db.insert(Users).values(userData);

		// and dont forget to call the Authenticate function
		let session = await Authenticate({id:user[0].id!},"10d");
		return NextResponse.json(session, { status: 200 });

	} catch (error) {
		return new Response("Something Wrong Happen", { status: 400 });
	}
}

in the client side call the GithubClient function and pass the client_id

1.3.13

9 months ago

1.2.12

9 months ago

1.3.12

9 months ago

1.2.11

9 months ago

1.2.10

10 months ago

1.2.9

10 months ago

1.2.8

10 months ago

1.0.3

10 months ago

1.0.2

10 months ago

1.0.1

10 months ago

1.0.0

10 months ago