Како имплементирати аутентификацију токеном у Нект.јс користећи ЈВТ

Провера аутентичности токеном је популарна стратегија која се користи за заштиту веб и мобилних апликација од неовлашћеног приступа. У Нект.јс можете да користите функције провјере аутентичности које пружа Нект-аутх.

Алтернативно, можете се одлучити за развој прилагођеног система аутентификације заснованог на токенима користећи ЈСОН веб токене (ЈВТ). На тај начин осигуравате да имате већу контролу над логиком аутентификације; у суштини, прилагођавање система да прецизно одговара захтевима вашег пројекта.

Подесите Нект.јс пројекат

Да бисте започели, инсталирајте Нект.јс тако што ћете покренути наредбу испод на свом терминалу.

 npx create-next-app@latest next-auth-jwt --experimental-app 

Овај водич ће користити Нект.јс 13 који укључује директоријум апликације.

Затим инсталирајте ове зависности у свој пројекат користећи нпм, Ноде Пацкаге Манагер.

 npm install jose universal-cookie 

Јосе је ЈаваСцрипт модул који пружа скуп услужних програма за рад са ЈСОН веб токенима док универзални колачић зависност пружа једноставан начин рада са колачићима претраживача и на клијентском и на серверском окружењу.

Креирајте кориснички интерфејс обрасца за пријаву

Отворите директоријум срц/апп, креирајте нови фолдер и назовите га за пријаву. Унутар ове фасцикле додајте нову датотеку паге.јс и укључите код испод.

 "use client";
import { useRouter } from "next/navigation";

export default function LoginPage() {
  return (
    <form onSubmit={handleSubmit}>
      <label>
        Username:
        <input type="text" name="username" />
      </label>
      <label>
        Password:
        <input type="password" name="password" />
      </label>
      <button type="submit">Login</button>
    </form>
  );
}

Код изнад креира функционалну компоненту странице за пријаву која ће приказати једноставан образац за пријаву у претраживачу како би се омогућило корисницима да унесу корисничко име и лозинку.

Изјава о употреби клијента у коду осигурава да је граница између кода само за сервер и кода само за клијента декларисана у директоријуму апликације.

У овом случају, користи се за декларисање да се код на страници за пријаву, посебно функција хандлеСубмит, извршава само на клијенту; у супротном, Нект.јс ће приказати грешку.

  8 начина да поправите немогућност слања поруке многим непосланим мултимедијалним порукама

Сада, хајде да дефинишемо код за функцију хандлеСубмит. Унутар функционалне компоненте додајте следећи код.

 const router = useRouter();

const handleSubmit = async (event) => {
    event.preventDefault();
    const formData = new FormData(event.target);
    const username = formData.get("username");
    const password = formData.get("password");
    const res = await fetch("/api/login", {
      method: "POST",
      body: JSON.stringify({ username, password }),
    });
    const { success } = await res.json();
    if (success) {
      router.push("/protected");
      router.refresh();
    } else {
      alert("Login failed");
    }
 };

За управљање логиком аутентификације за пријављивање, ова функција хвата корисничке акредитиве из обрасца за пријаву. Затим шаље ПОСТ захтев крајњој тачки АПИ-ја, преносећи податке корисника ради верификације.

Ако су акредитиви важећи, што указује да је процес пријављивања био успешан—АПИ враћа статус успеха у одговору. Функција руковатеља ће тада користити рутер Нект.јс да навигира корисника до одређене УРЛ адресе, у овом случају, заштићене руте.

Дефинишите крајњу тачку АПИ-ја за пријаву

Унутар директоријума срц/апп креирајте нову фасциклу и назовите је апи. Унутар ове фасцикле додајте нову датотеку логин/роуте.јс и укључите код испод.

 import { SignJWT } from "jose";
import { NextResponse } from "next/server";
import { getJwtSecretKey } from "@/libs/auth";

export async function POST(request) {
  const body = await request.json();
  if (body.username === "admin" && body.password === "admin") {
    const token = await new SignJWT({
      username: body.username,
    })
      .setProtectedHeader({ alg: "HS256" })
      .setIssuedAt()
      .setExpirationTime("30s")
      .sign(getJwtSecretKey());
    const response = NextResponse.json(
      { success: true },
      { status: 200, headers: { "content-type": "application/json" } }
    );
    response.cookies.set({
      name: "token",
      value: token,
      path: "https://www.makeuseof.com/",
    });
    return response;
  }
  return NextResponse.json({ success: false });
}

Примарни задатак за овај АПИ је да верификује акредитиве за пријаву прослеђене у ПОСТ захтевима користећи лажне податке.

Након успешне верификације, генерише шифровани ЈВТ токен повезан са детаљима аутентификованог корисника. Коначно, шаље успешан одговор клијенту, укључујући токен у колачићима одговора; у супротном, враћа одговор статуса грешке.

Имплементирајте логику верификације токена

Почетни корак у аутентификацији токена је генерисање токена након успешног процеса пријављивања. Следећи корак је имплементација логике за верификацију токена.

  Проверите да ли је ваш претраживач рањив на Спецтре

У суштини, користићете функцију јвтВерифи коју обезбеђује модул Јосе да верификујете ЈВТ токене прослеђене са наредним ХТТП захтевима.

У директоријуму срц, направите нову датотеку либс/аутх.јс и укључите код испод.

 import { jwtVerify } from "jose";

export function getJwtSecretKey() {
  const secret = process.env.NEXT_PUBLIC_JWT_SECRET_KEY;
  if (!secret) {
    throw new Error("JWT Secret key is not matched");
  }
  return new TextEncoder().encode(secret);
}

export async function verifyJwtToken(token) {
  try {
    const { payload } = await jwtVerify(token, getJwtSecretKey());
    return payload;
  } catch (error) {
    return null;
  }
}

Тајни кључ се користи за потписивање и верификацију токена. Упоређујући декодирани потпис токена са очекиваним потписом, сервер може ефикасно да провери да ли је обезбеђени токен валидан и на крају да овласти захтеве корисника.

Направите .енв датотеку у основном директоријуму и додајте јединствени тајни кључ на следећи начин:

 NEXT_PUBLIC_JWT_SECRET_KEY=your_secret_key 

Направите заштићену руту

Сада морате да креирате руту којој само провјерени корисници могу приступити. Да бисте то урадили, направите нову датотеку протецтед/паге.јс у директоријуму срц/апп. Унутар ове датотеке додајте следећи код.

 export default function ProtectedPage() {
    return <h1>Very protected page</h1>;
  }

Направите куку за управљање стањем аутентификације

Креирајте нову фасциклу у срц директоријуму и назовите га закаче. Унутар ове фасцикле додајте нову усеАутх/индек.јс датотеку и укључите код испод.

 "use client" ;
import React from "react";
import Cookies from "universal-cookie";
import { verifyJwtToken } from "@/libs/auth";

export function useAuth() {
  const [auth, setAuth] = React.useState(null);

  const getVerifiedtoken = async () => {
    const cookies = new Cookies();
    const token = cookies.get("token") ?? null;
    const verifiedToken = await verifyJwtToken(token);
    setAuth(verifiedToken);
  };
  React.useEffect(() => {
    getVerifiedtoken();
  }, []);
  return auth;
}

Ова кука управља стањем аутентификације на страни клијента. Он преузима и проверава валидност ЈВТ токена присутног у колачићима помоћу функције верифиЈвтТокен, а затим поставља аутентификоване податке о кориснику у стање аутентификације.

На тај начин омогућава другим компонентама да приступе и користе информације о аутентификованом кориснику. Ово је од суштинског значаја за сценарије као што је прављење ажурирања корисничког интерфејса на основу статуса аутентификације, накнадних захтева за АПИ или приказивање различитог садржаја на основу корисничких улога.

  Како да направите прилагођене позадине са градијентом за ваш иПхоне

У овом случају, користићете куку за приказивање различитог садржаја на почетној рути на основу стања аутентификације корисника.

Алтернативни приступ који бисте могли размотрити је руковање управљањем стањем користећи Редук Тоолкит или коришћење алата за управљање стањем као што је Јотаи. Овај приступ гарантује да компоненте могу добити глобални приступ стању аутентификације или било ком другом дефинисаном стању.

Само напред и отворите датотеку апп/паге.јс, избришите шаблон Нект.јс код и додајте следећи код.

 "use client" ;

import { useAuth } from "@/hooks/useAuth";
import Link from "next/link";
export default function Home() {
  const auth = useAuth();
  return <>
           <h1>Public Home Page</h1>
           <header>
              <nav>
                {auth ? (
                   <p>logged in</p>
                ) : (
                  <Link href="https://wilku.top/login">Login</Link>
                )}
              </nav>
          </header>
  </>
}

Код изнад користи усеАутх куку за управљање стањем аутентификације. При томе, условно приказује јавну почетну страницу са везом до путање странице за пријаву када корисник није аутентификован, и приказује пасус за аутентификованог корисника.

Додајте међуверски софтвер да бисте применили овлашћени приступ заштићеним рутама

У директоријуму срц, креирајте нову Миддлеваре.јс датотеку и додајте код испод.

 import { NextResponse } from "next/server";
import { verifyJwtToken } from "@/libs/auth";

const AUTH_PAGES = ["https://wilku.top/login"];

const isAuthPages = (url) => AUTH_PAGES.some((page) => page.startsWith(url));

export async function middleware(request) {

  const { url, nextUrl, cookies } = request;
  const { value: token } = cookies.get("token") ?? { value: null };
  const hasVerifiedToken = token && (await verifyJwtToken(token));
  const isAuthPageRequested = isAuthPages(nextUrl.pathname);

  if (isAuthPageRequested) {
    if (!hasVerifiedToken) {
      const response = NextResponse.next();
      response.cookies.delete("token");
      return response;
    }
    const response = NextResponse.redirect(new URL(`/`, url));
    return response;
  }

  if (!hasVerifiedToken) {
    const searchParams = new URLSearchParams(nextUrl.searchParams);
    searchParams.set("next", nextUrl.pathname);
    const response = NextResponse.redirect(
      new URL(`/login?${searchParams}`, url)
    );
    response.cookies.delete("token");
    return response;
  }

  return NextResponse.next();

}
export const config = { matcher: ["https://wilku.top/login", "/protected/:path*"] };

Овај међуверски код делује као чувар. Он проверава да би се осигурало да када корисници желе да приступе заштићеним страницама, они су аутентификовани и овлашћени за приступ рутама, поред тога што преусмерава неовлашћене кориснике на страницу за пријаву.

Обезбеђивање Нект.јс апликација

Провера аутентичности токеном је ефикасан безбедносни механизам. Међутим, то није једина доступна стратегија за заштиту ваших апликација од неовлашћеног приступа.

Да бисте ојачали апликације у односу на динамички пејзаж сајбер безбедности, важно је усвојити свеобухватан безбедносни приступ који холистички решава потенцијалне безбедносне рупе и рањивости како би се гарантовала темељна заштита.