I am using Mongoose and nodejs to write an API.
My users.js looks as follow:
var express = require('express');
var router = express.Router();
var user = require('../models/users.js');
router.post('/',function(req, res, next) {
console.log("made a post");
var user2 = new user(); // create a new instance of the Bear model
user2.firstName = req.body.firstName; // set the bears name (comes from the request)
user2.lastName=req.body.lastName;
user2.email=req.body.email;
user2.save(function(err) {
if (err)
res.send(err);
console.log("User created");
});
})
//The model acts as our user object...this returns all users.
.get('/', function(req, res, next) {
console.log("sending a get request");
user.find(function(err, users) {
if (err)
res.send(err);
res.json(users);
});
})
module.exports = router;
When I send a get request, it works perfectly. However, I am now trying to develop the POST request. I send a request such as the following:
http://localhost:4000/users?firstName=Han&lastName=Bo#email=haBo#yah.com
and I receive the following in my console:
sending a get request
GET /users?firstName=Han&lastName=Bo#email=haBo#yah.com
200 15.522 ms - 1365
And I receive the output of my GET request in the browser.
I'm new to node and would appreciate some help with this.
Thanks.
You are putting your parameters as URL parameters, while your POST API reads parameters from body of request.
Here is explanation of POST parameters.
Also, if you are not already using it, use postman to send requests.
Related
I am trying to redirect the user with a post request from the home page after checking if their sessions exist.
This is my home controller file:-
const express = require('express');
const router = express.Router();
router.get('/', (req, res, next) => {
if (req.session["Data"] != undefined) {
res.redirect(307, '/Try');
}
else {res.render('home', {pageTitle: "Home"});}
});
module.exports = router;
But it is giving me error- Cannot GET /Try
This is what I'm using in my route file- router.post('/Try', try_controller.Try);
I am using res.redirect(307, '/Try') in another controller file of the same project and it's working. I can't figure out why it's not working here.
I don't think you can redirect a GET as a POST. If you own the /Try route, one option is to add a GET handler for that, then redirect will work.
Otherwise, in your GET route handler for \ you can create a new POST and return the results of that.
const request = require('request')
router.get('/', (req, res, next) => {
if (req.session["Data"] != undefined) {
//res.redirect(307, '/Try');
request.post('/Try', {}, function(err, response, body) {
if (err) return next(err)
return res.status(response.statusCode).send(body);
})
}
else {res.render('home', {pageTitle: "Home"});}
});
The example above an https://github.com/request/request though there are more modern ways of sending POST from express.
This isn't technically "redirecting", so you won't return 307 or 302.
I tried different things but in the end, I added an empty form in my home.pug file and submitted it using js.
JS code -
script.
let ssn = !{JSON.stringify(session)};
data = "Data"
if (ssn[data] != undefined) {document.getElementById('form-id').submit();}
I have a sign up form that I want to re-populate with the user entered data when the form is submitted but has errors in them. I am using express-validator and connect-flash to check / show error messages. I can't seem to figure out a way to pass the original values back to repopulate the field.
Here's my route:
router.post('/edit',
// Input validation
function(req, res, next) {
req.checkBody('username', 'Username cannot be empty').trim().notEmpty();
var errors = req.validationErrors(true);
if (errors) {
req.flash('validation', errors);
res.redirect('/vendor/edit/'));
} else {
//Add to DB
}
});
Here is where I either load the original form, or where it gets redirected to show the form with error messages. :
router.get('/edit', function(req, res) {
res.render('vendor_edit', {
validation: req.flash('validation')[0],
error: req.flash('error')[0],
});
});
However, the form is blank when it gets redirected since my template doesn't have the original values, or I don't know how to access them if they are naturally passed? - I am trying to render in PUG.
This is made possible via this post:
How do I redirect in expressjs while passing some context?
For the lazy, here is the copy and paste of the code from the above link, it worked like a charm for me.
var express = require('express');
var jade = require('jade');
var http = require("http");
var app = express();
var server = http.createServer(app);
/////////////
// Routing //
/////////////
// Move route middleware into named
// functions
function homeCtrl(req, res) {
// Prepare the context
var context = req.dataProcessed;
res.render('home.jade', context);
}
function categoryCtrl(req, res, next) {
// Process the data received in req.body
// instead of res.redirect('/');
req.dataProcessed = somethingYouDid;
return next();
// optionally - Same effect
// accept no need to define homeCtrl
// as the last piece of middleware
// return homeCtrl(req, res, next);
}
app.get('/', homeCtrl);
app.post('/category', categoryCtrl, homeCtrl);
I am developing a site using the mean stack and express-jwt to block access to api calls to my site unless a user is authenticated. There are certain api calls that I need users not logged in to access, i.e., /api/login and /api/register. When I access the endpoints using firebug everything seems to work as expected, it blocks under the right conditions and allows under the right conditions. I am even receiving the token under firebug. However, if I test using mocha/chai I am getting "401 unauthorized" error indicating "No authorization token was found". I am using the following code to ignore selected endpoints:
app.js:
let expressJwt = require('express-jwt')
app.use(expressJwt({secret: process.env.AUTH_KEY}).
unless({path: ['/api/login', '/api/register', /^\/api\/external\/.*/]}));
routes.js:
module.exports = function(app, mongoose){
app.use("/api/register", require("./routes/registration")(mongoose));
app.use("/api/external/games", require("./routes/games")(mongoose));
app.use("/api/external/shopping", require("./routes/shopping")(mongoose));
}
routes/registration.js:
'use strict'
module.exports = function(){
const express = require('express');
const router = express.Router();
const RegistrationFactory = require('../factories/RegistrationFactory');
const registrationFactory = new RegistrationFactory();
router.use(function(req, res, next) {
next();
});
/* GET users listing. */
router.post('/', function(req, res, next) {
const registrationService = registrationFactory.create();
registrationService.register(req.body, function(err, user){
if (!err && user){
console.log(err);
res.sendStatus(200);
} else {
return next(err);
}
})
});
return router;
}
I would like to block access to all of the routes except the three listed above. Can someone point out what I am doing wrong because I am not seeing it? I am a newbie to node.js.
I'm trying to write a small api with Facebook authentication and as I'm new to node.js I'm just a little confused as to how I should structure this.
I have a route called auth.js that looks like this:
var express = require('express');
var crypto = require('crypto');
var rp = require('request-promise');
var router = express.Router();
router.post('/', function(req, res) {
rp('https://graph.facebook.com/me?access_token=' + req.body.fbAccessToken).then(function(body) {
var json = JSON.parse(body);
if(json.error) { res.status(403).send(json.error.message); }
var user = new User({
userId: json.id,
fbAccessToken: req.body.fbAccessToken,
apiAccessToken: crypto.randomBytes(64).toString('hex'),
firstName: json.first_name,
lastName: json.last_name,
email: json.email
});
user.save(function(err) {
if (err) throw err;
return user.userId;
});
}).then(function(userId) {
res.status(201).send('something');
}).catch(function(err) {
res.status(403).send(err);
});
});
module.exports = router;
When the route recieves a post it takes the Facebook token from the request and checks if it is legit using the Facebook graph API. (Apologies if the Promise stuff looks a little funky too, I'm trying to learn that as well).
Anyway, I have a User model and a user.js route too. What I want to know is if the User creation that happens in my auth route here should be moved to the User model and the model functions called from here somehow? Via the user route maybe?
Cheers
Yes and yes. I think user stuff can go under /user and it is cleaner if the user creation is in its own module.
BTW did you see fbgraph?
I m actually studying REST Apis security, and it seems that many people are using OAuth2 and OpenId protocoles to manage authentication.
I have tried to implement two OAuth2 server using :
http://passportjs.org/ for the client side and https://github.com/jaredhanson/oauth2orize for the server side
https://www.npmjs.org/package/node-oauth2-server
For the first solution, running the examples is working correctly but I need to make something stateless (and in the example the author uses sessions...)
Can you help me to create the simplest oauth2 server possible or defaultly explaining me the whole functionnement of these libraries ?
Thanks for advance
I implemented using "oauth2-server": "^3.0.0-b2"
var express = require('express');
var oauthServer = require('oauth2-server');
var Request = oauthServer.Request;
var Response = oauthServer.Response;
var authenticate = require('./components/oauth/authenticate')
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// https://github.com/manjeshpv/node-oauth2-server-implementation/blob/master/components/oauth/models.js
var oauth = new oauthServer({
model: require('./models.js')
});
app.all('/oauth/token', function(req,res,next){
var request = new Request(req);
var response = new Response(res);
oauth
.token(request,response)
.then(function(token) {
// Todo: remove unnecessary values in response
return res.json(token)
}).catch(function(err){
return res.status( 500).json(err)
})
});
app.post('/authorise', function(req, res){
var request = new Request(req);
var response = new Response(res);
return oauth.authorize(request, response).then(function(success) {
res.json(success)
}).catch(function(err){
res.status(err.code || 500).json(err)
})
});
app.get('/secure', authenticate(), function(req,res){
res.json({message: 'Secure data'})
});
app.get('/me', authenticate(), function(req,res){
res.json({
me: req.user,
messsage: 'Authorization success, Without Scopes, Try accessing /profile with `profile` scope',
description: 'Try postman https://www.getpostman.com/collections/37afd82600127fbeef28',
more: 'pass `profile` scope while Authorize'
})
});
app.get('/profile', authenticate({scope:'profile'}), function(req,res){
res.json({
profile: req.user
})
});
app.listen(3000);
To simulate, Use Postman: https://www.getpostman.com/collections/37afd82600127fbeef28
MySQL/PostgreSQL/MSSQL Compatiable: https://github.com/manjeshpv/node-oauth2-server-implementation/blob/master/components/oauth/models.js
MySQL DDL: https://github.com/manjeshpv/node-oauth2-server-implementation/blob/master/sql/oauth_demo.sql
Mongo Dumps: https://github.com/manjeshpv/node-oauth2-server-implementation/tree/master/mongo-dump
Note that they have an issue there with the validateScope function needs to be replaced with:
function validateScope(user, client) {
return user.scope === client.scope
}