如何在graphql中使用passport-local

Kev*_*vin 8 passport-local passport.js graphql apollo-server

我正在尝试在我的项目中实现 GraphQL,我想passport.authenticate('local')在我的登录中使用Mutation

我想要的代码改编:

const typeDefs = gql`
type Mutation {
      login(userInfo: UserInfo!): User
    }
`

 const resolvers = {
    Mutation: {
      login: (parent, args) => { 
        passport.authenticate('local')
        return req.user
    }
}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. passport设计多为REST / Express吗?
  2. 我可以操作passport.authenticate方法(将用户名和密码传递给它)吗?
  3. 这甚至是一种常见做法还是我应该坚持使用一些 JWT 库?

Dan*_*den 11

Passport.js 是一个“兼容 Express 的身份验证中间件”。authenticate返回一个 Express 中间件函数——它旨在防止对特定 Express 路由的未授权访问。它不太适合在解析器中使用。如果您通过req上下文将对象传递给解析器,则可以调用req.login以手动登录用户,但在将user对象传递给函数之前,您必须验证凭据并自己创建对象。同样,您可以调用req.logout手动注销用户。有关文档,请参见此处

如果您想使用 Passport.js,最好的做法是为您正在使用的每个标识提供程序创建一个带有授权路由和回调路由的 Express 应用程序(请参阅示例)。然后使用apollo-server-express. 您的客户端应用程序将使用授权路由来初始化身份验证流程,回调端点将重定向回您的客户端应用程序。然后,您可以添加req.user到您的上下文并在解析器、指令、GraphQL 中间件等中检查它。

但是,如果您使用本地策略,您可能会考虑完全放弃 Passport 并自己处理事情。


jke*_*ann 9

我花了一些时间来思考 GraphQL 和 Passport 的组合。尤其是当您想将本地策略与登录突变一起使用时,会使事情变得复杂。这就是为什么我创建了一个名为graphql-passport的小型 npm 包。

这是服务器设置的样子。

import express from 'express';
import session from 'express-session';
import { ApolloServer } from 'apollo-server-express';
import passport from 'passport';
import { GraphQLLocalStrategy, buildContext } from 'graphql-passport';

passport.use(
  new GraphQLLocalStrategy((email, password, done) => {
    // Adjust this callback to your needs
    const users = User.getUsers();
    const matchingUser = users.find(user => email === user.email && password === user.password);
    const error = matchingUser ? null : new Error('no matching user');
    done(error, matchingUser);
  }),
);

const app = express();
app.use(session(options)); // optional
app.use(passport.initialize());
app.use(passport.session()); // if session is used

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: ({ req, res }) => buildContext({ req, res, User }),
});

server.applyMiddleware({ app, cors: false });

app.listen({ port: PORT }, () => {
  console.log(` Server ready at http://localhost:${PORT}${server.graphqlPath}`);
});
Run Code Online (Sandbox Code Playgroud)

现在,您将可以通过 GraphQL 上下文访问特定于护照的功能和用户。这是您编写解析器的方式:

const resolvers = {
  Query: {
    currentUser: (parent, args, context) => context.getUser(),
  },
  Mutation: {
    login: async (parent, { email, password }, context) => {
      // instead of email you can pass username as well
      const { user } = await context.authenticate('graphql-local', { email, password });

      // only required if express-session is used
      context.login(user);

      return { user }
    },
  },
};
Run Code Online (Sandbox Code Playgroud)

GraphQL 和 Passport.js 的结合是有道理的。特别是如果您想添加更多身份验证提供程序,例如 Facebook、Google 等。如果需要,您可以在此博客文章中找到更多详细信息。