Как аутентифицировать пользователя на основе файлов cookie?

#authentication #cookies #jwt #apollo

Вопрос:

Я настроил свой клиент и сервер Apollo для работы с файлами cookie:

Клиент:

   const httpLink = createHttpLink({
    uri: 'http://localhost:9090/graphql',
    credentials: 'include',
  });

  const cache = new InMemoryCache();

  const client = new ApolloClient({
    link: httpLink,
    cache,
  });
 

Сервер:

   const app = express();
  const server = new ApolloServer({
    resolvers,
    typeDefs,
    context: async ({req, res}) => ({
      req,
      res,
      prisma,
    }),
  });
  await server.start();

  const corsOptions = {
    origin: 'http://localhost:8080',
    credentials: true,
  };

  app.use(cors(corsOptions));
  app.use(express.urlencoded({
    extended: true,
  }));
  server.applyMiddleware({
    app, cors: corsOptions,
  });

  app.listen({port: 9090}, () =>
    console.log(`🚀 Server ready at http://localhost:9090${server.graphqlPath}`),
  );
 

распознаватель логинов:

   loginUser: async (_, args, {req, res}) => {
    const theUser = await prisma.user.findUnique({
      where: {email: String(args.email)},
    });
    if (!theUser) throw new Error('Unable to Login');
    const isMatch = bcrypt.compareSync(args.password, theUser.password);
    if (!isMatch) throw new Error('Unable to Login');

    const token = jwt.sign(theUser, 'supersecret');

    res.cookie('id', token, {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      maxAge: 1000 * 60 * 60 * 24 * 7,
    });

    return true;
  },
 

Когда я вхожу в свое приложение React, сервер устанавливает файл cookie, как и ожидалось, но я не уверен в том, как использовать этот файл cookie клиента для аутентификации моего пользователя на сервере и как сохранить статус входа в систему. Файл cookie также добавляется в запрос.

Это файл cookie только по протоколу http, поэтому я не могу использовать информацию о файлах cookie в клиенте. Поэтому я думаю, что мне нужна функция, которая запрашивает мутацию входа в систему каждый раз при загрузке приложения, а затем на сервере я могу проверить запрос, если в файлах cookie запроса есть токен JWT, я могу аутентифицировать пользователя.

Но я надеялся получить некоторые отзывы об этом подходе.

Ответ №1:

Основываясь на вашем распознавателе логина, файл cookie должен быть включен в массив файлов cookie req (вы можете использовать более уникальный идентификатор файла cookie, чем «идентификатор», и вам следует извлечь секрет из файла env). Вы можете добавить это промежуточное программное обеспечение на свой сервер, чтобы проверять и проверять файлы cookie при каждом запросе:

 app.use((req, use, next) => {
    const { id } = req.cookies;
    if (id) {
        const { user } = jwt.verify(
            id,
            process.env.SUPERSECRET
        );
        // put the user onto the req for future requests to access
        req.user = user;
    }
    next();    
});
 

Вместо того, чтобы помещать в файл cookie всего пользователя, вы можете просто включить идентификатор пользователя, а затем добавить еще один компонент промежуточного программного обеспечения для запроса данных пользователя, используя этот идентификатор при каждом запросе.