简体   繁体   中英

How Azure AD B2C can authenticate with GraphQL (Apollo Server) API and ReactJs

In the documentation there is a sample react app is authenticating with nodejs ( expressJs - REST API ) link is here: https://docs.microsoft.com/en-us/azure/active-directory-b2c/configure-authentication-sample-react-spa-app

but there is nothing written about react App with Nodejs (GraphQL-Apollo Server) API authentication. Please help me as i want to apply authentication same as written in the documentation for REACT -NODEJS ( but with graphQL-Apollo Server API ) but there is no clue on the internet about it.

Solution So after trying several things i found a solution to my question. So first of all use apollo-server-express. This library enables you to attach Apollo Server to an Express server.

const { ApolloServer, gql } = require(apollo-server-express);
const http =require(http)
const {ApolloServerPluginDrainHttpServer, ApolloServerPluginLandingPageLocalDefault,ApolloServerPluginLandingPageGraphQLPlayground,
  ApolloServerPluginLandingPageDisabled,ApolloServerPluginLandingPageProductionDefault} = require(apollo-server-core)
const express = require(express)
const BearerStrategy = require(passport-azure-ad).BearerStrategy;
const config = require(./config.json);
const passport = require(passport);
const cors = require(cors)

const options = {
    identityMetadata: `https://${config.metadata.b2cDomain}/${config.credentials.tenantName}/${config.policies.policyName}/${config.metadata.version}/${config.metadata.discovery}`,
    clientID: config.credentials.clientID,
    audience: config.credentials.clientID,
    policyName: config.policies.policyName,
    isB2C: config.settings.isB2C,
    validateIssuer: config.settings.validateIssuer,
    loggingLevel: config.settings.loggingLevel,
    passReqToCallback: config.settings.passReqToCallback,
    scope: config.protectedRoutes.hello.scopes
}

const bearerStrategy = new BearerStrategy(options, (token, done) => {
        // Send user info using the second argument
        done(null, { }, token);
        console.log(token)
    }
);

 const typeDefs = gql`
 
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;
const books = [
    {
      title: 'The Awakening',
      author: 'Kate Chopin',
    },
    {
      title: 'City of Glass',
      author: 'Paul Auster',
    },
  ];

 const resolvers = {
    Query: {
      books: () => books,
    },
  };


  async function startApolloServer(typeDefs, resolvers) {

    // Required logic for integrating with Express
 
    const app = express();
    app.use(cors({ origin: true }))
    passport.use(bearerStrategy)

    const getUser = (req, res) =>
      new Promise((resolve, reject) = {
        passport.authenticate('oauth-bearer', { session: false }, (err, user) = {
          if (err) reject(err)
          resolve(user)
          console.log(user)
        })(req, res)
      })
    
    const httpServer = http.createServer(app);
  
    const server = new ApolloServer({

      typeDefs,
      resolvers,
      context:  async ({ req, res }) => {
        const user = await getUser(req, res)                             
        if (!user) throw new AuthenticationError('No user logged in')
        console.log('user found'; user)
  
        return { user }
      },
     
      csrfPrevention: true,
      cache: bounded
      plugins: [
        ApolloServerPluginDrainHttpServer({ httpServer }),
        ApolloServerPluginLandingPageLocalDefault({ embed: true }),  

     process.env.NODE_ENV === production;
      ? ApolloServerPluginLandingPageDisabled()                              // turning playground off in production isn't really a thing anymore
      : ApolloServerPluginLandingPageGraphQLPlayground(),
       
      ],
    });
  
    // More required logic for integrating with Express
    
    await server.start();
    
    server.applyMiddleware({
      app,
      path:/hello;
    });
    await new Promise(resolve =httpServer.listen({ port: 5000 }, resolve));
    console.log(`Server ready at http://localhost:5000${server.graphqlPath}`);
  }

  
  startApolloServer(typeDefs,resolvers)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM