사용자 지정 SessionData 개체 및 TypeScript와 함께 express-session을 사용하는 방법

이 블로그 게시물은 express-session의 session 개체에서 사용자 정의 데이터를 사용하려는 문제가 있는 사용자를 위한 것입니다. 제 경우에는 user 객체였습니다.

TS2339: Property 'user' does not exist on type 'Session & Partial '.


제가 처음에 사용했던 솔루션(다른 곳에서도 추천합니다)과 express-session이 추천하는 솔루션을 보여드리겠습니다.

문제



성공적인 사용자 로그인 후 세션에 사용자 개체를 저장한다고 가정해 보겠습니다.

export const oauthCallback = async (
  req: express.Response,
  res: express.Response,
) => {
  try {
    const code = req.query.code;
    const {
      response: { access_token, refresh_token },
    } = await client.exchangeOAuthCodeForAccessToken(code);
    const { response } = await client.retrieveUserInfoFromAccessToken(access_token);
    const userEmail = response.email;
    const {
      response: { user },
    } = await client.retrieveUserByEmail(userEmail as string);

    // assign User to express-sessions session object
    req.session.user = user;

    res.redirect(
      302,
      `${PRIVATE_URI_SCHEME_REDIRECT}?` +
        `access_token=${access_token}&` +
        `refresh_token=${refresh_token}`,
    );
  } catch (error) {
    res.json(error.message);
  }
};


TypeScript 엄격 모드를 활성화한 경우 이 코드에서 발생하는 첫 번째 오류는 다음과 같습니다.

TS2339: Property 'user' does not exist on type 'Session & Partial '.




이것은 TypeScript가 usersession 객체를 인식하지 못하기 때문입니다.

해결 방법 1 - 이 작업을 수행하지 마십시오.



내가 보는 일반적인 수정은 express.Request 필드를 사용하여 user 개체를 확장하는 것입니다.

export type SessionRequest = express.Request & {
  session: {
    user: User;
  };
};


그러나 라우터 콜백을 이 서명으로 변경한 후:
router.get("/account", async (req: SessionRequest, res: express.Response) => {
함수의 반환 유형에 대한 오류가 발생하기 시작합니다.

TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '(req: SessionRequest, res: express.Response) => Promise<void>' is not assignable to parameter of type 'Application<Record<string, any>>'.
    Type '(req: SessionRequest, res: Response<any, Record<string, any>>) => Promise<void>' is missing the following properties from type 'Application<Record<string, any>>': init, defaultConfiguration, engine, set, and 61 more.




이 방법으로도 할 수 있지만 이 작업을 수행하기 위해 다른 모든 것을 패치하는 토끼 구멍으로 내려가고 싶지 않았습니다. 대신:

솔루션 2 - 더 나은 방법



나는 express-session의 TypeScript 문서에 대해 더 자세히 알아보기로 결정했고 다음을 발견했습니다.

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express-session/index.d.ts#L211-L224:

    /**
     * This interface allows you to declare additional properties on your session object using [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html).
     *
     * @example
     * declare module 'express-session' {
     *     interface SessionData {
     *         views: number;
     *     }
     * }
     *
     */
    interface SessionData {
        cookie: Cookie;
    }


최상위 TypeScript 파일 중 하나에 이 선언 병합을 추가하기만 하면 됩니다. 나는 이것을 별도의 express-session.d.ts에 추가하려고 시도했지만 작동하지 않았습니다.

결국 server.ts 에 추가했는데 제 경우에는 백엔드의 주요 진입점입니다.

// server.ts
import express from "express";
import session from "express-session";

...
type User = {
  id: string;
  email: string;
};

// Augment express-session with a custom SessionData object
declare module "express-session" {
  interface SessionData {
    user: User;
  }
}

const CI = process.env.CI;

const server = express().disable("x-powered-by");
...


이렇게 하면 평소와 같이 경로 콜백을 유지할 수 있습니다.

router.get("/account", async (req: express.Request, res: Response) => {


하지만 세션에 사용자 지정.user 개체도 있었습니다.



윈윈✌️

이것이 익스프레스 세션에서 사용자 지정 데이터를 올바르게 입력하는 데 도움이 되기를 바랍니다!

좋은 웹페이지 즐겨찾기