React 및 GraphQL - 04를 사용하여 Reddit 클론 만들기

여기에서 찾을 수 있는 이 기사의 코드베이스.

rasikag/reddit-clone

이제 이 애플리케이션에 대한 사용자 인증을 구현하겠습니다. 이를 위해 쿠키를 사용한 세션 인증을 사용하고 있습니다.

이를 위해 Session를 사용합니다. 그것은 우리 서버의 사용자에 대한 일부 데이터를 저장합니다. 서버에 데이터를 저장하기 위해 Redis 인메모리 데이터베이스를 사용합니다. 그것은 정말 빠르고 사용자가 로그인했는지 여부를 확인하는 데 필요한 모든 요청입니다.

아래 가이드에 따라 Redis를 설치할 수 있습니다.

Redis Quick Start - Redis

그런 다음 여기에서 찾을 수 있는 모든 세부 정보connect-redis.를 사용하고 있습니다.

tj/connect-redis

설치하려면 아래 명령을 추가하십시오.

yarn add redis connect-redis express-session

redis는 Redis 클라이언트입니다. 그런 다음 connect-redis는 Redis 클라이언트용 커넥터입니다. express-session는 서버 측 세션 관리자입니다.

이제 connect-redis 의 예제에서 아래 코드를 복사하십시오. 변환require하면 이 오류가 발생합니다.

could not find a declaration file for module redis


이는 유형 지원을 추가해야 함을 의미합니다. 그렇게하려면 아래 모듈을 추가하십시오.

yarn add -D @types/redis @types/express-session @types/connect-redis


이제 이 코드 비트를 메인 함수 내부와 Apollo 미들웨어 앞으로 이동합니다. Apollo 미들웨어가 Redis를 사용하기 때문에 순서가 중요합니다. 그래서 우리는 그 전에 시작해야 합니다.


const RedisStore = connectRedis(session);
const redisClient = redis.createClient();

app.use(
  session({
    store: new RedisStore({ client: redisClient }),
    secret: "keyboard cat",
    resave: false,
  })
);
const apolloServer = new ApolloServer({
  schema: await buildSchema({
    resolvers: [HelloResolver, PostResolver, UserResolver],
    validate: false,
  }),
  context: () => ({ em: orm.em }),
});



이제 세션 개체에 몇 가지 설정을 추가합니다.
disableTouch : true
이렇게 하면 세션이 영원히 유지됩니다. TTL(Time to Live)을 정의할 필요가 없고 사용자가 무언가를 할 때마다 클라이언트는 세션 시간을 새로 고침하라는 요청을 보내야 합니다. 이를 통해 서버 호출을 줄일 수 있습니다.
name 소품.

쿠키의 이름입니다. ( qid )
maxAge 쿠키의 속성

쿠키의 최대 연령
httpOnly 쿠키의 소품

이 소품은 프런트 엔드 JavaScript 코드가 쿠키에 액세스할 수 없음을 정의합니다. 보안에 좋습니다.
secure 쿠키의 소품

이렇게 하면 https 환경에서만 이 쿠키를 만들고 사용할 수 있습니다.
sameSite 쿠키의 소품

이것은 csrf 공격으로부터 보호합니다.
saveUninitialized 거짓으로

이 prop을 추가하지 않으면 prop을 추가하지 않아도 세션이 생성됩니다. 빈 세션을 추가할 필요가 없습니다. 이를 방지하려면 이 소품을 추가하십시오.

이제 요청 및 응답 개체를 사용하도록 RedditContext 파일을 변경합니다. 이렇게 하면 유형 지원을 사용할 수 있습니다. 그런 다음 ApolloServer 개체에 전달합니다.

...
context: ({ req, res }: RedditDbContext) => ({ em: orm.em, req, res }),
...


자, 이제 사용자 등록에 세션을 추가합니다. 먼저 req 리졸버에 register 매개변수를 추가합니다.

...
@Ctx() { em,req }: RedditDbContext
...


그런 다음 session 개체에 액세스할 수 있습니다. session 객체 안에 무엇이든 저장할 수 있습니다. 여기서는 userId 만 있으면 됩니다.


req.session.userId = user.id


그러나 여기서 오류가 발생합니다.

Property 'userId' does not exist on type 'Session & Partial<SessionData>'.



이를 수정하기 위해 아래와 같이 RedditContextrequest 객체에 추가합니다.

req: Request  & {session: Session & Partial<SessionData> & {userId: number}};
// this & sign will join these types together


자, 이 시점에서 모든 설정이 완료되었으며 이것을 테스트할 것입니다. 먼저 로컬 호스트의 GraphQL 놀이터 설정에서 일부 설정을 변경해야 합니다. 거기에서 "request.credentials”: “omit”“request.credentials”: “include” 로 변경하십시오. 이것이 작동하지 않는 한.

쿠키를 확인하려면 개발자 도구를 열고 응용 프로그램 섹션을 선택하십시오. 로그인 쿼리를 사용하여 로그인을 시도하고 성공적으로 로그인하면 이름이 qid인 쿠키와 쿠키 값이 표시됩니다.

여기에서 이 메모를 마무리하겠습니다. 곧 이 메모의 다음 부분을 게시할 것입니다.

이와 관련하여 질문할 사항이 있으면 여기에 댓글을 남겨주세요. 또한 내 이해에 따라 이것을 썼습니다. 따라서 잘못된 점이 있으면 주저하지 말고 저를 수정하십시오. 정말 감사합니다.

오늘의 친구들을 위한 것입니다. 곧 봐요. 고맙습니다.

참조:

이 기사 시리즈는 .

기본 이미지credit

좋은 웹페이지 즐겨찾기