Apollo express 没有快速护照会话

Posted

技术标签:

【中文标题】Apollo express 没有快速护照会话【英文标题】:Apollo express don't have express passport session 【发布时间】:2019-07-09 05:49:41 【问题描述】:

对于我们的门户,我将我的快递服务器与护照集成在一起以验证用户身份。一旦用户通过身份验证,需要使用来自客户端的相同会话从我们的 api 获取用户的详细信息。护照身份验证适用于我的门户,并且能够查看登录用户的身份提供者数据。但是当从反应端执行任何 GraphQL 调用时,Apollo 服务器的请求中没有用户会话,但 express 有。

按照此处提到的步骤https://www.apollographql.com/docs/apollo-server/essentials/server.html#ssl,但是在为 ApolloServer 设置上下文时,req 在其会话中没有护照。

        const express = require('express');
        const session = require('express-session');
        const  ApolloServer  = require('apollo-server-express');
        const addResolveFunctionsToSchema = require('graphql-tools').addResolveFunctionsToSchema;
        const mongooseConnection = require('./src/persistence/mongooseConnection');
        const MongoSession = require('connect-mongo')(session);
        const config = require('config');
        const mongo = config.get('mongo');
        const fs = require('fs');
        const https = require('https');
        const bodyParser = require('body-parser');
        const cookieParser = require('cookie-parser');
        const configSession = config.get('session');
        const configPassport = config.get('passport');
        const configCommon = config.get('common');
        const resolvers = require('./src/resolvers');
        const schema = require('./src/schema');
        const uri = `$mongo.uri/$mongo.database`;
        const app = express();
        var passport = require('passport');
        const SamlStrategy = require('passport-saml').Strategy;
        const authRoute = require('./routes/auth');

        const apiRoute = require('./routes/userDetails');
        const Helmet = require('helmet');
        require('reflect-metadata');

        mongooseConnection.create();

        let mongoOptions = ;

        const mongoSessionStore = new MongoSession(
            url: `$uri`,
            mongoOptions: mongoOptions,
            collection: configSession.mongo.collection
        );
        addResolveFunctionsToSchema(schema, resolvers);

        passport.use(
            new SamlStrategy(
                
                    entryPoint: configPassport.entry_point,
                    // issuer: 'passport-saml',
                    protocol: 'https',
                    callbackURL: `$configCommon.dns/$configPassport.callback_url`,
                    // cert: adfsTokenSigningCert,
                    identifierFormat: null,
                    forceAuthn: true,
                    signatureAlgorithm: 'sha256',
                    acceptedClockSkewMs: -1
                ,
                (profile, cb) => 
                    cb(null, profile);
                
            )
        );

        passport.serializeUser(function(user, done) 
            done(null, userData);
        );

        passport.deserializeUser(function(obj, done) 
            done(null, obj);
        );

        app.use(cookieParser());

        app.use(
            session(
                secret: 'project',
                secret: configSession.config.secret,
                resave: false,
                saveUninitialized: false,
                store: mongoSessionStore,
                sameSite: true,
                rolling: true,
                name: 'project',
                cookie: 
                    secure: true,
                    domain: configCommon.cookie_domain
                
            )
        );

        // Initialize Passport
        app.use(passport.initialize());
        app.use(passport.session());
        app.use(bodyParser.json());
        app.use(
            bodyParser.urlencoded(
                extended: false
            )
        );
        // setting up security headers
        app.use(Helmet());

        app.get('/s/health-check', (req, res) => 
            res.send(`I am alive!!!!`);
        );

        app.use('/s/api', apiRoute);
        app.use('/s/auth', authRoute); // API integration

        const isDev = process.env.NODE_ENV !== 'prod';

        const apolloServer = new ApolloServer(
            schema,
            resolvers,
            context: ( req ) => 
                console.log(req) //req.session don't have passport in it
                return 
                    req
                ;
            
        );

        apolloServer.applyMiddleware(
            app,
            path: '/graphql'
        );

        apolloServer.installSubscriptionHandlers(app);

        https
            .createServer(
                
                    key: fs.readFileSync(`./keys/server.key`),
                    cert: fs.readFileSync(`./keys/server.crt`)
                ,
                app
            )
            .listen(process.env.PORT, () => 
                console.log('Express server is running on port 9091');
            );

        // Handle uncaughtException
        process.on('uncaughtException', err => 
            console.log(err.message);
            process.exit(1);
        );

【问题讨论】:

【参考方案1】:

仔细检查请求是否正在发送会话 cookie。我遇到了同样的问题,我使用 Graphql Playground 作为客户端,默认情况下它禁用发送 cookie。您可以通过转到操场右上角的设置并设置"request.credentials": "same-origin" 来修复它。在我这样做之后,我看到护照会话已正确初始化。

【讨论】:

伙计,非常感谢你,我已经 3 天了,我更改了很多会话管理包,但没有任何改变。

以上是关于Apollo express 没有快速护照会话的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS express - 如何在路由器内添加会话数据?

与护照、mongodb 和 express 的持久会话

不在护照快递服务器上保存会话

禁用 cookie 时的护照会话管理

快速护照会话不起作用

Express CORs 策略阻止 Apollo 客户端从服务器获取