get response from webserver with ajax - node.js

i am beginner in ajax and i decided to use jquery ajax for this moment , and before using ajax i created simple login / signup pages and i used bodyparser for requests
and when password or username is incorrect it reloads and then sends response to user that one of them is incorrect, and as i know ajax works without reload and
how can i add ajax when info is incorrect while login here is code
app.post('/login',
async (req, res) => {
try {
const { username, password } = req.body;
const user = await User.findOne({ username, password }).select('-password').lean();
if (!user) {
res.send('User: ' + username + ' not registered');
return;
}
req.session.user = user;
res.redirect('/dash')
return res.status(200).send('Session ID: ' + req.sessionID);
}
catch (error) {
res.status(500).send(error.message);
}
});

Try some thing like this:
$('#login-button').on('click', function(event) {
event.preventDefault();
var username = $('#username').val(), password = $('#password').val();
$.ajax({
type: 'POST',
data: JSON.stringify({ username: username, password: password }),
contentType: "application/json; charset=utf-8",
url: 'http://localhost:8000/login',
success: function(sessionID) {
console.log(sessionID);
},
error: function(xhr, status, err) {
var errMsg = xhr.responseText; // Your error msg
$('#errMsg').html(errMsg);
}
});
});

Related

Login with Node and React

I'm creating a very simple login with React and Node as part of an assignment at school, no authentication needed.
This is my code:
Server.js
app.post('/auth', function (request, response) {
var username = request.body.username;
var password = request.body.password;
if (username && password) {
response.redirect('/home');
} else {
response.send('Please enter Username and Password!');
response.end();
}
});
and this is my front end
Loggin.js
handleLogin = () => {
const { username, password } = this.state;
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
user: {
username: username,
password: password
}
})
};
fetch('http://localhost:8080/auth', requestOptions)
.then(response => response.json())
.then(data => {
console.log(data.success)
if (data.success) {
window.location = "/home";
}
});
}
But is not working. When I console.log username and password it says undefined
I have been trying to find a solution before to post here but I can not find it, and I do not know what am I doing wrong.
Any help would be appreciated.
The problem is that the frontend sends a body of type:
body = {
user: {
username: 'value',
password: 'value'
}
}
but on the backend you read username and password directly from the body object. Either update your backend logic to:
app.post('/auth', function(request, response) {
var username = request.body.user.username;
var password = request.body.user.password;
if (username && password) {
response.redirect('/home');
} else {
response.send('Please enter Username and Password!');
response.end();
}
});
or your frontend one to:
body: JSON.stringify({
username: username,
password: password
});
Your react application expects a JSON answer but receives a plain text.
try something like
response.json({error: 'Please enter Username and Password!'});

How to handle login with MongoDB through REST API?

I'm not sure how to check if the values match with the MongoDB data. I am using PUT and trying to use findOneAndUpdate to check if the values match.
<script>
const logindetails = new Vue({
el: '#logindetails',
data: {
email: "",
password: "",
on: Boolean
},
methods: {
login: function (e) {
e.preventDefault();
const log = {
email: this.email,
password: this.password,
}
const options = {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(log)
};
fetch('http://localhost:3000/users/${this.email}/${this.password}',
options).then(response => {
[...]
</script>
This is the server code (it successfully connected to MongoDB) :
app.put('/students/:email/:password', (req, res, next) => {
console.log("login");
res.setHeader("Content-Type", "application/json");
db.collection('users').findOne({email: (req.params.email), password: (req.params.password)},
{$set: {on: true}})
.then(results => res.send(results))
.catch(err => res.send(err))
});
I personally don't think it is a good idea to put your username and password as query string, because it hurts the restful api convention. It wouldn't make sense to use a put request if there is no body being pass. Also, a post request would make more sense in a login situation .Anyway I digress, here are the usual steps to doing authentication.
1. (Client-Side) Send the email and password in the body of the fetch request
//something like this
const body = { email, password };
const response = await fetch(
"http://localhost:5000/authentication/login",
{
method: "POST",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(body)
}
);
2.(Server-Side - make sure you to use app.use(express.json()) to access req.body)
//defining middleware to access req.body
app.use(express.json());
app.post("/authentication/login", async(req,res) =>{
//1. destructure email and password
const {email, password} = req.body
//2. check if user doesn't exist
const user = await db.user.find({user_email: email})
if(!user){
return res.status(401).send("User does not exist");
}
//3. Check if password is the same as the password in the database
if(password !== user.password){
return res.status(401).send("Wrong Credential")
}
//4. This is up to you when the user is authenticated
res.json(`Welcome back ${email}`);
})

JSON webtoken login authorisation for react and express protected routes

I am struggling to make a login system using JSON web tokens.
I have made the login (client side) that calls to my server.js file.
This is the login through the client side Below is my handle submit function that calls the server.js login route.How would I use a token here?
handleSubmit(e) {
e.preventDefault();
if (this.state.email.length < 8 || this.state.password.length < 8) {
alert(`please enter the form correctly `);
} else {
const data = { email: this.state.email, password: this.state.password };
fetch("/login", {
method: "POST", // or 'PUT'
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(data => {
console.log("Success:", data);
})
.catch(error => {
console.error("Error:", error);
});
}
}
catch(e) {
console.log(e);
}
This is the login route for my server.js. As you can see I have assigned a jwt but how would I send this back to my login form and utilise it for protected routes.
app.post("/login", async (req, response) => {
try {
await sql.connect(config);
var request = new sql.Request();
var Email = req.body.email;
var Password = req.body.password;
console.log({ Email, Password });
request.input("Email", sql.VarChar, Email);
request.input("Password", sql.VarChar, Password);
const result = await request.execute("dbo.LoginUser");
if (result.recordsets[0].length > 0) {
console.info("/login: login successful..");
console.log(req.body);
const token = jwt.sign({ user: Email }, "SECRET_KEY", {
expiresIn: 3600000
});
var decoded = jwt.verify(token, "SECRET_KEY");
console.log(decoded);
response.status(200).json({
ok: true,
user: Email,
token: token
});
console.log(token);
} else {
console.info("/login: bad creds");
response.status(400).send("Incorrect email and/or Password!");
}
} catch (err) {
console.log("Err: ", err);
response.status(500).send("Check api console.log for the error");
}
});
Essentially all I want is for my submit handler to be called for login. Server returns a jwt token which can then be used to verify other routes.
There are two ways to route:
Use React-Redux and react-router.
Save the fetched JWT token into localStorage and use to validate route within your routes component.
I would recommend in using React-Redux / React-router for protected routing.
Here is a video link to Build Real Web App with React by
Rem Zolotykh
This will help you.

How to use Facebook Graph API with passport-facebook in NodeJS with Express

Before Asking this Question I have referred the below but didn't help me
Passport.js & Facebook Graph API
Retrieving photo from Facebook using passport-facebook
https://www.hitchhq.com/facebook-graph-api/docs/facebook-authentication
http://tech.bigstylist.com/index.php/2017/08/12/search-facebook-graph-api-nodejs/
How to use Facebook Graph API after authenticating with Passport.js facebook strategy?
enter link description here
And Some posts say to use passport-facebook-token But I don't want to use as I want to extend the existing functionality of my application with passport-facebook only
Problem Statement
Currently, I am using passport-facebook for authentication which works perfectly and Now I want to extend the functionality to use Facebook Graph API to get the photos of the users who log in to my application
So use the Facebook Graph API to get the user photos I have to make below call using request module in Node JS, The body part will return me the expected result
var request = require("request");
var options = {
method: 'GET',
url: 'https://graph.facebook.com/me/photos/',
qs: {
access_token: 'EBBCEdEose0cBADwb5mOEGISFzPwrsUCrXwRWhO87aXB9KsVJlgSLc19IdX9D9AKU7OD5SdFOqPXW3eLm8J3HltZC14VexdMsEDW35LDWASdVDNGp5brFERBETsIvxXJIFXo7QSum5apHXeRyQk7c2PQljmf5WHObZAwXVzYjqPd4lziKTUK48Wfrw5HPwZD'
},
headers: {
'content-type': 'application/json'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
But now I wanted to create my custom express GET API when I call that I use should be getting the above body response,
like GET : /graph/photos
app.get('/graph/photos', function (req, res) {
res.send(body)//Here I wanted to get the same response as of the request module above
});
But I have the below challenges
Getting the access_token from the passport-facebook and pass that to the request module
If the user is not authenticated thrown an error in the API response
But I could able to proceed somewhat with below approach, I have followed the tutorial from
https://github.com/scotch-io/easy-node-authentication/tree/linking
app.get('/graph/photos', isLoggedIn, function (req, res) {
var hsResponse = request({
url: 'https://graph.facebook.com/me/photos',
method: 'GET',
qs: {
"access_token": req.user.facebook.token
},
}, function (error, response, body) {
res.setHeader('Content-Type', 'application/json');
res.send(body);
});
});
But the problem I am facing is every time call the API /graph/photos/, It will try to redirect to check whether the user is logged in hence I won't be directly able to use in Angular Service and getting below error
Error
Failed to load http://localhost:3000/graph/photos: Redirect from 'http://someurl' to 'http://someurl' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
try this...
I wrote the function for my project,you just customize....
// facebook login
exports.facebookLogin = function(req, res) {
var fields = config.loginFaceBook.fbFields;
var accessTokenUrl = config.loginFaceBook.fbAccessTokenUrl;
var graphApiUrl = config.loginFaceBook.fbGraphApiUrl + fields.join(',');
var params = {
code: req.body.code,
client_id: req.body.clientId,
client_secret: config.loginFaceBook.fbClientSecret,
redirect_uri: req.body.redirectUri
};
// Step 1. Exchange authorization code for access token.
request.get({
url: accessTokenUrl,
qs: params,
json: true
}, function(err, response, accessToken) {
console.log('Exchange authorization code err::', err);
console.log('Exchange authorization code accessToken::', accessToken);
if (response.statusCode !== 200) {
return res.status(500).send({
message: accessToken.error.message
});
}
// Step 2. Retrieve profile information about the current user.
request.get({
url: graphApiUrl,
qs: {
access_token: accessToken.access_token,
fields: fields.join(',')
},
json: true
}, function(err, response, profile) {
console.log('Retrieve profile information err::', err);
console.log('Retrieve profile information::', profile);
if (response.statusCode !== 200) {
return res.status(500).send({
message: profile.error.message
});
}
if (req.header('Authorization')) {
console.log('req header Authorization', req.header('Authorization'));
} else {
var socialEmail;
if (profile.email) {
socialEmail = profile.email;
} else {
socialEmail = profile.id + '#facebook.com';
}
// Step 3. Create a new user account or return an existing one.
UserModel.findOne({
email: socialEmail
}, function(err, existingUser) {
if (existingUser) {
AppClientModel.findOne({
_id: config.auth.clientId
}, function(err, client) {
if (!err) {
var refreshToken = generateToken(existingUser, client, config.secrets.refreshToken);
var rspTokens = {};
rspTokens.access_token = generateToken(existingUser, client, config.secrets.accessToken, config.token.expiresInMinutes);
var encryptedRefToken = cryptography.encrypt(refreshToken);
var token = {
clientId: client._id,
refreshToken: refreshToken
};
UserModel.update({
_id: existingUser._id
}, {
$push: {
'tokens': token
}
}, function(err, numAffected) {
if (err) {
console.log(err);
sendRsp(res, 400, err);
}
res.cookie("staffing_refresh_token", encryptedRefToken);
sendRsp(res, 200, 'Success', rspTokens);
});
}
});
}
if (!existingUser) {
var userName = profile.first_name + ' ' + profile.last_name;
var newUser = new UserModel({
name: userName,
img_url: 'https://graph.facebook.com/' + profile.id + '/picture?type=large',
provider: 2, //2: 'FB'
fb_id: profile.id,
email_verified_token_generated: Date.now()
});
log.info("newUser", newUser);
newUser.save(function(err, user) {
if (!err) {
var refreshToken = generateToken(user, client, config.secrets.refreshToken);
var rspTokens = {};
rspTokens.access_token = generateToken(user, client, config.secrets.accessToken, config.token.expiresInMinutes);
var encryptedRefToken = cryptography.encrypt(refreshToken);
var token = {
clientId: client._id,
refreshToken: refreshToken
};
UserModel.update({
_id: user._id
}, {
$push: {
'tokens': token
}
}, function(err, numAffected) {
if (err) {
console.log(err);
sendRsp(res, 400, err);
}
res.cookie("staffing_refresh_token", encryptedRefToken);
sendRsp(res, 200, 'Success', rspTokens);
});
} else {
if (err.code == 11000) {
return sendRsp(res, 409, "User already exists");
} else {
return sendRsp(res, 500, "User create error");
}
}
});
}
});
}
});
});
};

how to redirect using Rest API to HTML page in nodejs

I have created login api, i want to redirect to
homepage after login successfully.
code:
router.post('/login', function(req, res, next) {
var session = req.session;
var username = req.body.username;
var password = req.body.password;
User.findOne({
username: username,
password: password
}, function(err, user) {
if (err) {
console.log(err);
return res.status(500).json("Error");
}
if (!user) {
return res.status(404).json("User Not Found");
}
session.isLogin = true;
return res.status(200).json("Login Successfully!!!");
res.redirect('/public/modules/login/homepage.html');
});
});
Seems you use angular.js redirect should happen on client side. You should return success status code from backend and in front-end use ui-router $state.go('home') method see this article to get started in ui-router: https://scotch.io/tutorials/angular-routing-using-ui-router
$scope.submit = function() {
$http({
method: "POST",
url: "localhost:3000/api/login";,
data: {
"username": $scope.login.username,
"password": $scope.login.pā€Œā€‹ assword
}
}).then(function mySucces(response) {
alert('success');
$state.go('home');
}, function myError(response) {
$scope.myWelcome = response.statusText;
});
}

Resources