【问题标题】:Windows authentication using Express and GraphQL使用 Express 和 GraphQL 的 Windows 身份验证
【发布时间】:2019-03-20 11:01:47
【问题描述】:

我正在尝试为我的 React 应用程序(使用 apollo 客户端)实现窗口身份验证。我使用apollo graphql server 作为后端。我使用node-sspi 来获取Windows 登录用户。

以下是我的服务器端代码。如果添加 app.use(function (req, res, next) {http://localhost:9000/graphiql 将不起作用。也没有让 windows 登录用户名。

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const expressJwt = require('express-jwt'); //auth
const jwt = require('jsonwebtoken'); //auth
const db = require('./db');

const port = process.env.PORT || 9000;
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')

const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

// authentication middleware
const authMiddleware = expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
})

app.use(cors(), bodyParser.json(), authMiddleware);

app.use(function (req, res, next) {
  var nodeSSPI = require('node-sspi')
  var nodeSSPIObj = new nodeSSPI({
    retrieveGroups: true
  })
  nodeSSPIObj.authenticate(req, res, function(err){
    res.finished || next()
  })
})

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user && db.students.get(req.user.sub)}
})));
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

app.post('/login', (req, res) => {
   const userName = req.connection.user; // USERNAME undefined
   // LDAP Authenticate 
   const token = jwt.sign({sub: userName}, jwtSecret);
   res.send({token});
});

app.listen(
   port, () => console.info(
      `Server started on port ${port}. use http://localhost:${port}/graphiql`
   )
);

【问题讨论】:

    标签: node.js express graphql


    【解决方案1】:

    我做了一些变通后得到了解决方案。

    服务器端代码

    const bodyParser = require('body-parser');
    const cors = require('cors');
    const express = require('express');
    const expressJwt = require('express-jwt'); //auth
    const jwt = require('jsonwebtoken'); //auth
    const db = require('./db');
    
    const port = process.env.PORT || 9000;
    const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
    const app = express();
    
    const fs = require('fs')
    const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
    const resolvers = require('./resolvers')
    
    const {makeExecutableSchema} = require('graphql-tools')
    const schema = makeExecutableSchema({typeDefs, resolvers})
    
    // authentication middleware
    const authMiddleware = expressJwt({
       secret: jwtSecret,
       credentialsRequired: false
    })
    
    app.use(cors(), bodyParser.json(), authMiddleware);
    
    //Setup endpoint routes
    var router = express.Router();
    //Basic Router Config
    router.use(function(req, res, next){
    
       var nodeSSPI = require('node-sspi')
       //Integrated Authentication for Windows
       var nodeSSPIObj = new nodeSSPI({
           retrieveGroups: true
       });
    
       try{
           nodeSSPIObj.authenticate(req, res, function(err){
               res.finished || next();
           });
       }
       catch(err)
       {
           res.status(500).send(JSON.stringify({status: 500, message: "Something went wrong", detail: err.message}));
       }
    });
    
    // windows
    router.get('/', function(req, res){
       // Do LDAP authentication or whatever
    
       const token = jwt.sign({authUser: req.connection.user}, jwtSecret);
       res.send({token});
    });
    
    // Regular login
    router.post('/login', (req, res) => {
       const email = req.body.email;
       const password = req.body.password;
    
       const user = authenticateUser // SQL/mongo/etc..
       const token = jwt.sign({authUser: user.id}, jwtSecret);
       res.send({token});
    });
    
    app.use('/api', router);
    
    const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
    app.use('/graphql', graphqlExpress((req) => ({
       schema,
       context: {user: req.user && req.user.authUser}
    })));
    app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
    
    app.listen(
       port, () => console.info(
          `Server started on port ${port}. use http://localhost:${port}/graphiql`
       )
    );
    

    在客户端,我使用 Ajax Jquery 调用 POC。

    对于windows登录

    $.ajax({
    url: "http://localhost:9000/api",
    contentType: "application/json",
    xhrFields: {
      withCredentials: true
    },
    type: "GET",
    data: '',
    success: function (response) {
      loginToken = response.token;
          },
    error: (xhr, err) => alert('error')
    })
    

    使用登录凭据

    var email =  $("#txtEmail").val();
    var password =  $("#txtPwd").val();
    if(email && password) {
       $.ajax({
          url:"http://localhost:9000/api/login",
          contentType:"application/json",
          type:"POST",
          xhrFields: {
                 withCredentials: true
          },
          data:JSON.stringify({email,password}),
          success:function(response) {
                 loginToken =  response.token;   
          },
          error:(xhr,err) =>  alert('error')
          })
    }else alert("email and pwd empty")
    

    对于 GraphQL 查询

    $.ajax({url: "http://localhost:9000/graphql",
            contentType: "application/json",
            headers: {"Authorization": 'bearer '+ loginToken},
            type:'POST',
            data: JSON.stringify({
            query:`{greetingWithAuth}` }),
            success: function(result) {
                      console.log(result.data.greetingWithAuth")
            },
            error: func
           }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 2020-12-04
      • 2018-12-02
      • 1970-01-01
      • 2016-12-01
      • 1970-01-01
      • 2018-06-22
      相关资源
      最近更新 更多