gpt4 book ai didi

express - 如何使用 Passport 验证 GraphQL 端点?

转载 作者:行者123 更新时间:2023-12-01 11:18:08 27 4
gpt4 key购买 nike

我有一个 GraphQL 端点:

app.use('/graphql', graphqlHTTP(request => ({
graphiql: true,
schema
})));

我还有一个用于登录的 Passport 路由(并处理回调,因为我使用的是 Google OAuth2):

this.app.get('/login', passport.authenticate('google'));
this.app.get('/auth/callback/google', ....

Passport 将用户添加到请求中,我可以在网上找到的所有文章都建议使用该方法在我的每个 GraphQL 解析器中进行身份验证:

resolve: (root, args, { user }) => {
if (!user) throw new NotLoggedInError();

但是,当它适用于所有解析器时,必须将该逻辑添加到每个解析器是没有意义的,所以我希望以某种方式对整个端点进行身份验证。

问题是我不确定如何组合中间件。我尝试了以下方法,但它只是破坏了端点:

app.use('/graphql',  passport.authenticate('google'), graphqlHTTP(request => ({
graphiql: true,
schema
})));

最佳答案

我有以下工作。我遇到的一些问题是确保启用了我的 google API 并启用了正确的范围。我也只在 auth 端点上使用 passport 中间件,并使用 isAuthenticated 中间件来检查 session 是否已通过身份验证,如果没有则重定向到 auth 端点。还将请求对象放入上下文中,以便解析器可以使用它来潜在地授权用户。您当然需要更新用户查找,因为我只是传递模拟数据。

import express from "express";
import graphqlHTTP from "express-graphql";
import passport from "passport";
import cookieParser from "cookie-parser";
import session from "express-session";
import { Strategy as GoogleStrategy } from "passport-google-oauth20";
import { buildSchema } from "graphql";

const PORT = 5000;

const data = [
{ id: "1", name: "foo1" },
{ id: "2", name: "foo2" },
{ id: "3", name: "foo3" },
];

const def = `
type Foo {
id: String!
name: String
}
type Query {
readFoo(id: String!): Foo
}
schema {
query: Query
}
`;
const schema = buildSchema(def);
const fieldMap = schema.getType("Query").getFields();
fieldMap.readFoo.resolve = (source, args) => {
return data.filter(({ id }) => id === args.id)[0] || null;
};

passport.serializeUser((user, done) => {
done(null, user);
});

passport.deserializeUser((obj, done) => {
done(null, obj);
});

passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: `http://localhost:${PORT}/auth/google/callback`,
},
(accessToken, refreshToken, profile, cb) => {
return cb(null, {
id: "1",
username: "foo@bar.baz",
googleId: profile.id,
});
}
)
);

function isAuthenticated(req, res, next) {
return req.isAuthenticated() ? next() : res.redirect("/auth/google");
}

const app = express();
app.use(cookieParser());
app.use(
session({
secret: "sauce",
resave: false,
saveUninitialized: false,
})
);
app.use(passport.initialize());
app.use(passport.session());

app.get("/auth/fail", (req, res) => {
res.json({ loginFailed: true });
});

app.get(
"/auth/google",
passport.authenticate("google", { scope: ["profile"] })
);

app.get(
"/auth/google/callback",
passport.authenticate("google", { failureRedirect: "/auth/fail" }),
(req, res) => {
res.redirect("/graphql");
}
);

app.use(
"/graphql",
isAuthenticated,
graphqlHTTP((req) => ({
schema,
graphiql: true,
context: req,
}))
);

app.listen(PORT, () => {
console.log("Started local graphql server on port ", PORT);
});


关于express - 如何使用 Passport 验证 GraphQL 端点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47899786/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com