DEV Community

Cover image for Check Login Using Middleware With NextJS 13
Hòa Nguyễn Coder
Hòa Nguyễn Coder

Posted on

Check Login Using Middleware With NextJS 13

Create a Middleware that checks user login. Here, I have already prepared a BackEnd processing server .
So in this article, we only need to fetch the api and process the returned value. If you have not seen the previous article about Middleware, you can review this link: Create A Middleware In NextJS 13 - hoanguyenit.com
*CREATE A API FOLDER IN PROJECT *

  • _app/api/login/route.ts _ In this route.ts file , we will send ( username , _password _) to the backend server to check login. If correct, access_token will be returned
import { NextRequest, NextResponse } from "next/server";
type RequestBody = {
  email: string;
  password: string;
};

export async function POST(request: NextRequest) {
  const body: RequestBody = await request.json();
  const value = {
    email: body.email,
    password: body.password,
  };
  const res = await fetch("https://127.0.0.1:8000/api/auth/login", {
    method: "POST",
    mode: "cors",
    cache: "no-cache",
    credentials: "same-origin",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(value),
  });
  const data = await res.json();
  if (data.success) {
    // Then set a cookie
    const response = NextResponse.json(
      {
        success: data.success,
      },
      { status: 200 }
    );

    response.cookies.set({
      name: "login",
      value: "true",
      httpOnly: true,
    });
    response.cookies.set({
      name: "access_token",
      value: data.access_token, //token value here
      httpOnly: true,
      maxAge: data.expires_in,
    });
    return response;
  }
  return new NextResponse(null, {
    status: 404,
    statusText: "Bad request",
    headers: {
      "Content-Type": "text/plain",
    },
  });
}
Enter fullscreen mode Exit fullscreen mode

The backend will return data like ( access_token , expires_in ), we can use this data to store it as cookies .

const response = NextResponse.json(
      {
        success: data.success,
      },
      { status: 200 }
    );

    response.cookies.set({
      name: "login",
      value: "true",
      httpOnly: true,
    });
    response.cookies.set({
      name: "access_token",
      value: data.access_token, //token value here
      httpOnly: true,
      maxAge: data.expires_in,
    });
Enter fullscreen mode Exit fullscreen mode

Check Login using Middleware with NextJS 13 - hoanguyenit.com

CREATE A MIDDLEWARE

  • middleware.ts : used to check access_token , whether it exists or not by using request.cookie.get('access_token')
import { NextRequest, NextResponse } from "next/server";
const allow_origin_lists :string[]   = process.env.NODE_ENV==='production'?['https://hoanguyenit.com','https://100daysofcode.hoanguyenit.com']:
['https://www.google.com','http://localhost:3000','http://127.0.0.1:3000']
export default function middleware(request: NextRequest){
    const login = request.cookies.get("login");
    const check_login= !login?.value? false: true
    const access_token = request.cookies.get("access_token");
    const check_token = !access_token?.value? false: true
    const origin: string | null  = request.headers.get('origin')
    const res = NextResponse.next()
//    console.log(request.nextUrl.pathname);
    const res_404 = new NextResponse(null,
        {
            status: 404,
            statusText:"Bad request",
            headers:{
                'Content-Type':'text/plain'
            }
        })

    if(origin && !allow_origin_lists.includes(origin)){
        return res_404;
    }
    if(!check_login && !check_token){
        return res_404;
    }
    console.log("origin",origin);
    res.headers.append('Access-Control-Allow-Credentials', "true")
    res.headers.append('Access-Control-Allow-Origin', origin) 
    res.headers.append('Access-Control-Allow-Methods', 'GET,DELETE,PATCH,POST,PUT')
    res.headers.append(
        'Access-Control-Allow-Headers',
        'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'
    )

    return res;
}
export const config = {
    matcher:[
        '/api/categories:path*',
        '/api/post:path*',
        '/api/user:path*'
    ]
}
Enter fullscreen mode Exit fullscreen mode

In the above code, we check the values ​​in the cookie that we saved in the login section above

const login = request.cookies.get("login");
const check_login= !login?.value? false: true
const access_token = request.cookies.get("access_token");
const check_token = !access_token?.value? false: true
//nếu không đúng trả về status 404
if(!check_login && !check_token){

    return res_404; 
}
Enter fullscreen mode Exit fullscreen mode

Here, we need middleware to request the following api routes:

export const config = {
    matcher:[
        '/api/categories:path*',
        '/api/post:path*',
        '/api/user:path*'
    ]
}
Enter fullscreen mode Exit fullscreen mode

Okay so we have created Middleware.

Now we need to create a user api folder to get that user's information. If everything in the middleware is correct, it will allow us to call api/user/

  • app/api/user/route.ts
import { NextRequest, NextResponse } from 'next/server'
type ResponseBody = { errors: { message: string }[] } | { username: string };
async function getUserByValidSessionToken(token : string){

    const res = await fetch('http://127.0.0.1:8000/api/auth/user-profile',{
         headers: {
           "Content-Type": "application/json",
           "Authorization":"Bearer "+token
         },
    });

    const data = await res.json();
    return {
      username: data.name
    }
}

export async function GET(
    request: NextRequest
  ): Promise<NextResponse<ResponseBody>> {
    const token = request.cookies.get("access_token");
    const user = !token?.value
      ? undefined
      : await getUserByValidSessionToken(token.value);

    if (!user) {
      return NextResponse.json({
        errors: [{ message: "User not found by session token" }],
      });
    }

    return NextResponse.json({
      username: user.username,
    });
Enter fullscreen mode Exit fullscreen mode

Get the access_token value in the cookie

const token = request.cookies.get("access_token");
    const user = !token?.value
      ? undefined
      : await getUserByValidSessionToken(token.value);
Enter fullscreen mode Exit fullscreen mode

Write fucntion fetch api + token

const res = await fetch('http://127.0.0.1:8000/api/auth/user-profile',{
         headers: {
           "Content-Type": "application/json",
           "Authorization":"Bearer "+token
         },
});
Enter fullscreen mode Exit fullscreen mode

Create A Middleware In NextJS 13 - hoanguyenit.com
Okay that's it, you can develop further

Top comments (0)