首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Express和GraphQL的Windows身份验证

使用Express和GraphQL的Windows身份验证
EN

Stack Overflow用户
提问于 2019-03-16 15:37:33
回答 1查看 307关注 0票数 0

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

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

代码语言:javascript
复制
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`
   )
);
EN

回答 1

Stack Overflow用户

发布于 2019-03-19 22:14:07

在做了一些变通方法后,我找到了解决方案。

服务器端代码

代码语言:javascript
复制
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登录

代码语言:javascript
复制
$.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')
})

使用登录凭据

代码语言:javascript
复制
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查询

代码语言:javascript
复制
$.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
       }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55194519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档