Before going to question, please note, I have tried many suggestions from stackoverflow as well as many other websites. There are many suggestions, but most of them truly dont solve this question straight.
My question in simple one sentence is, how to let my web server (which is a node js express based api) know, the logged windows user id (from my react js application) in an intranet application?
Till now I am able to write express based node js server which uses node-sspi library and provides me the windows user id and groups. This API is as simple as
var express = require('express');
var app = express();
var server = require('http').createServer(app);
let cors = require('cors')
app.use(cors())
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();
});
});
app.get('*', function (req, res, next) {
res.json({msg: '************ Server reply by user ' + req.connection.user})
});
// Start server
var port = process.env.PORT || 3002;
server.listen(port, function () {
console.log('Express server listening on port %d in %s mode', port, app.get('env'));
});
React App.js code is
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
msg: "Not known",
localdata:"local status",
status:"not set",
};
}
componentDidMount()
{
fetch('http://192.168.7.179:3002/',{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json',
},
})
.then(response =>
{
this.state.status = response.status;
return response.text();
}
)
.then(msg =>
this.setState({ msg })
);
}
render() {
return (
<div className="App">
<div> LocalData is - {this.state.localdata}</div>
<div> Server data is - {this.state.msg} </div>
api call status is - { this.state.status }
</div>
);
}
}
export default App;
In the above code, If you do API call from browser you get correct reply
http://192.168.7.179:3002/
{"msg":"************ Server reply by user IUYT\\user1"}
But, from react app
LocalData is - local status
Server data is -
api call status is - 401
in F12 window
Failed to load resource: the server responded with a status of 401 (Unauthorized)
Please suggest changes required for calling from react app.
After researching finally got a breakthrough yesterday. So thought to answer my own question.
5 points to change in my example.
We need to refer both client and server with IP addresses or domains for communication purposes. So I changed all api calls origin mentions to their respective IP addresses.(localhost -> 192...)
In cors, we need to mention IP address and port number as origin
So Total change to my code in the example is,
In server side
var corsOptions = {
origin: 'http://192.168.7.179:3001',
credentials: true,
authenticate: true,
authorization: true,
optionsSuccessStatus: 200
}
app.use(cors(corsOptions))
instead of
app.use(cors())
and in client side add 'credentials: 'include'' as parameter to fetch.
change
fetch('http://192.168.7.179:3002/',{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json',
}
})
to
fetch('http://192.168.7.179:3002/',{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
credentials: 'include'
})
Thats it, first run api then launch when you launch your react app and you will get a prompt for windows auth. Fill in your domain credentials and server will fetch results.
Steps 1. In browser see if server is running -> http://192.168.7.179:3002/
{"msg":"************ Server reply by user IUYT\user1"}
LocalData is - local status
Server data is - Not known
api call status is - not set
BUT
LocalData is - local status
Server data is - {"msg":"************ Server reply by user IUYT\user1"}
api call status is - 200