카테고리 없음

[NextJS] 20260419 인증 패키지 - lucia

magpiebros 2026. 4. 19. 22:39

사용자 인증을 하기 위해서는 서버와 클라이언트간의 세션 유지가 필요하다.

이걸 다 만들수는 없으니.. 

패키지를 설치 하여 처리 하겠다.

 

https://lucia-auth.com/

 

Lucia

An open source resource on implementing authentication with JavaScript

lucia-auth.com

 

npm install lucia @lucia-auth/adapter-sqlite

 

위 명령어는 lucia 패키지를 설치하고, lucia가 배포한 패키지 중에서 sqlite를 사용하라는 의미이다.

 

 

import { Lucia } from 'lucia';
import { BetterSqlite3Adapter } from '@lucia-auth/adapter-sqlite';

import db from './db';

const adapter = new BetterSqlite3Adapter(db, {
    user: 'users',
    session: 'sessions',
});

const lucia = new Lucia(adapter, {
    sessionCookie: {
        expires: false,
        attributes: {
            secure: process.env.NODE_ENV === 'production'
        }
    }   
});

 

패키지를 설치한후, lucia를 만들어 줄수 있다.

expires: false로 설정하면 만료가 없는것으로 보일수 있지만, 그 반대의 경우다.

이렇게 lucia를 설정해주었다면 실제 세션을 만드는 함수를 구성한다.

 

export async function createAuthSession(userId) {
    const session = await lucia.createSession(userId, {});
    const sessionCookie = lucia.createSessionCookie(session.id);
    cookies().set(
        sessionCookie.name, 
        sessionCookie.value, 
        sessionCookie.attributes
    );
    return session;
}

 

위 코드를 통해서 클라이언트로 쿠키를 만들어 던져 줄수 있다.

 

마지막으로 세션 확인을 하는 방법이다.

export async function verifyAuth() {
    const sessionCookie = cookies().get(lucia.sessionCookie.name);
    if (!sessionCookie) {
        return {
            user: null, 
            session: null
        }
    }

    const sessionId = sessionCookie.value;
    if (!sessionId) {
        return {
            user: null, 
            session: null
        }
    }

    const result = await lucia.validateSession(sessionId);

    try {
        // 세션 생성
        if (result.session && result.session.fresh) {
            const sessionCookie = lucia.createSessionCookie(result.session.id);
            cookies().set(
                sessionCookie.name, 
                sessionCookie.value, 
                sessionCookie.attributes
            );
        }
        // 세션 제거
        if (!result.session) {
            const sessionCookie = lucia.createBlankSessionCookie();
            cookies().set(
                sessionCookie.name, 
                sessionCookie.value, 
                sessionCookie.attributes
            );
        }
    } catch {
        console.error('리프레시 쿠키 생성 중 오류 발생');
    }

    return result;
}

 

세션이 있으면 새로 세션을 만들어 연장해주고, 세선이 비정상적이면 삭제해주는 코드다.

 

 

추가로 bind 함수에 대해 설명해보자..

  const [formState, formAction] = useFormState(auth.bind(null, mode), {});

 

상황에 따라서는 form action이 다르게 동작되어야 할 경우가 있다.

이때, auth라는 함수를  server action에 정의 해주고, 인자를 통해 다른 함수를 반환해서 사용할 수 있다.

첫번째 인자는 this를 어디를 참조할지이고, 다음부터는 인자 값이다.

 

예를 들면 아래와 같다.

 

export async function auth(mode, prevState, formData) {
    if (mode === 'login') {
        return login(prevState, formData);
    }
    return signup(prevState, formData);
}

 

순서는 내가 정의해준 인자가 먼저 들어오고, arg1, arg2... 형태로 들어간다.

오늘 학습은 꽤 많이 한것같다..