How do I submit and process request params with an Oauth request? - node.js

I am using the MeanJS stack to develop a web application. The issue I'm having, is that my regular signup process has some unique parameters that are not common to an Oauth user profile. So, when I have the user go to signup with facebook, I move them to a new Signup form, that has them fill in the extra parameters, and then click "signup with facebook."
The routes are the same as the common MeanJS routes found here:
https://github.com/meanjs/mean/blob/master/app/routes/users.server.routes.js
Specifically these lines:
app.route('/auth/facebook').get(passport.authenticate('facebook', {
scope: ['email']
}));
app.route('/auth/facebook/callback').get(users.oauthCallback('facebook'));
What I would like to do, is have the extra parameters attached to the request object, so that when the auth process reaches the exports.saveOAuthUserProfile inside of: https://github.com/meanjs/mean/blob/master/app/controllers/users/users.authentication.server.controller.js
this function will be able to access those parameters and save them as part of the user model.
I have tried attaching parameters to the Get request and accessing
req.params.paramId
but this will not work, because you cannot register a param loaded request with the facebook api (or at least it seems to be that way).
And I have read elsewhere on StackOverflow that you can load the request State, but that seems really odd to me. Here's the link for that: Facebook OAuth: custom callback_uri parameters
So, any guidance on how to load the extra data into the Oauth request, so that when I save the user profile I can access it and save it, would be great.
Thanks guys.

It's not really clear to me what you want to achieve. What are the "extra" fields, and why don't you derive the fields from the user's profile directly?. About 98% of the FB Login implementations I've seen just use the "Login with Facebook" button and get the user's data during the OAuth process itself, and not manually entered by the user.
With passport-facebook for example, it's possible that you
a) Configure custom scopes
https://github.com/jaredhanson/passport-facebook#extended-permissions
b) Enrich the profile object with the custom scope's data
https://github.com/jaredhanson/passport-facebook#profile-fields
The profile object will then contain the additional requested fields automatically, and you don't need to tweak the request object itself.

Related

Handle multiple users in Node js Express application

I am new to NodeJs, and as a practice I am trying to build a blogging API using node and express. I am looking for a way to implement the following tasks :
Any user should be able to look at other user's profile, but not edit it.
Any user should be able to view any blog but edit only their own blogs
The way I was thinking of doing this is :
When a user logs in, store the user's id in a cookie (either a JWT token or something else), and whenever a profile / blog is to be displayed, check if the author of the blog / profile has the same Id as the one stored in cookie, if it is then allow the option to edit, else don't.
Would like to know if this is correct way to do it, also are there any better ways to achieve this ?
A better approach is to use an authentication middleware:
This blog post briefed it: https://medium.com/quick-code/handling-authentication-and-authorization-with-node-7f9548fedde8
The explanation of the concept is that you do not need to add the auth middleware to the user's profile GET endpoint (i.e the endpoints that gets user profile).
To edit a blog you need to do some checks if the id of the one who created the blog post matches.
I have a project you can check: https://github.com/razaqfatiu/Teamwork/blob/develop/api/controllers/article.js
The editArticle function on line 41 should be of help

Node.js / Express Passing Data Between Pages Without Messing Up RESTful Routing

I have an Express app, where the landing page invites people to enter their email address and then click on "Sign Up" or "Log In", depending on whether they have an account yet or not.
The user is then taken to "/signup" or "/login", via a POST request so that the email address they entered can be passed along.
But now that I've used POST for both of these routes, I have to POST to another URL to process their sign up data or log in credentials, like app.POST("/register") and app.POST("/enter"). This feels pretty sloppy, and definitely messes with the RESTful routing that I'd like to stick to.
I know I can pass the data through the URL via a GET request, but I don't really like that solution either.
What's the best approach to take in this situation? Should I just use GET requests and stop being so fussy? Or is there another way I haven't though of yet?
Thank you kind peoples!
I can see why you feel this messes with the RESTful approach, and an alternative method would be to store the email address client-side and not POSTing it to the server - until they actually sign up.
You could use the LocalStorage Web API to store the email address in the client browser, and then load it when the user hits the /signup route.
let email = document.querySelector('input[name="email"]').value
localStorage.set('email', email)
then later on when the user hits the /signup route you would do:
let email = localStorage.get('email')
document.querySelector('input[name="email"]').value = email
This would have to be in a <script> tag for the two routes.
You could also use sessionStorage which gets cleared when the user closes their browser, while localStorage is a permanent storage solution.
You can use /signup and /login GET request for rendering UI. And /signup and /login POST requests for processing

How can I create an authenticated scraper for Amazon product detail in Node.js?

I'm creating a script that grabs all the shipped items from Amazon and notifies me.
Authentication is needed to see the products though.
I've already tried sending a post request through "request" which returns an error because of the cookies and extra parameters needed.
It would be easy using cheerio afterwards to get the data if the authentication works.
Does anyone have any idea on how we can authenticate successfully?
The link from the email is: https://www.amazon.com/ap/signin/185-3199906-8918341?_encoding=UTF8&accountStatusPolicy=P1&openid.assoc_handle=usflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2Fgp%2Fyour-account%2Forder-details%2F185-3199906-8918341%3Fie%3DUTF8%26eoid%3D1%253A1%253Arv%252FYwjiYmnOZY9MYltVnDyf2l6p5pMkMx9deoUeiiw%252FKpPrtZrWqs5l1GGQPVb%2520qaJqHXyCkPEpLZnmDZamKkVDWhtu3dKlW5Gx7Uvxtzs0xlPJ25vduijJrPpHt79P%2520RRZHopOtAyOP4s82VLoeeiDQgq%2520FCP540H%2520UYAV7goZQxB29WObWAVh8VveTwEeWenY3sTx8ZI9%252FBLM2BSqS3IUIURW8mzMnAB9t7wglUiAcoR%252FcUhSIx%25201eNV4MspVAp7fLkeANag72BxgmsjFfRhnsxfji1VhZXLawqFeK9SBnvbUfkNWUC%2520IXWh6VcuoStBG3x%2520ZUkzGHw1ORi4J%2520Hg%253D%253D%26orderID%3D105-6914722-5422613%26ref_%3DTE_simp_on_T1&pageId=webcs-yourorder&showRmrMe=1
You cannot guarantee any of the form input values of the sign in page. So you must also scrape the login form.
Here is the process:
In your server, make Request to the URL in your question
Using Cheerio parse the DOM and grab all of the form fields from "#ap_signin_form".
Add in your data (Username/Pass) then make a POST request to the form action "https://www.amazon.com/ap/signin" (This should also be scraped)
Hopefully that will get you past the login screen. You will need to ensure all future requests pass the cookies set from login.
Now this kind of thing is clearly against most TOS's so I would urge caution in doing this kind of thing often.

ExpressJs route redirect

I have a widget for user to get information regarding books. The UX of the widget changes according to the fact that the user is logged in or not. Now I have a route for logged-in user(say, /user/getBookInfo) to get the book information(which includes sending sms n email logic). For users who are not logged-in I have created a different route(say, /public/getBookInfo), which includes some additional processing too. However retrieving the book information, sms and email logic etc is already present in '/user/getBookInfo'. I don't want to duplicate this function.
One option is call res.redirect('/user/getBookInfo') from /public/getBookInfo . However I want to avoid the redirect in this way.
So My question is How can I reuse this logic in /public/getBookInfo without using redirect??
Probably the best way in a Node.js application is to make a separate module, and put the common logic there. Then you can require the module in both routing files.

Hide querystring in url using MVC 5

Hi i have this application that needs a user to login.
Once the user is logged in, he is redirected to a page displaying documents for that user.
To display that information, I call the correct action on the controller and i pass my user-object. This object contains username and password.
When i look at my url it looks like :
http://localhost:53703/Documents?UserName=bart&UserId=10&Password=AllPhi%242015
Is there a way that I can hide those querystring-values (UserName=bart&UserId=10&Password=AllPhi%242015)
I can not object strongly enough to sidestepping the built in auth-mechanisms, but to answer the question: You cannot hide the query-string.
If you want to hide data when you are sending from a client you need to do a post request instead of a get, but the post-data is still visible in the request (in plain text)
But in this case it seems you want to pass data between actions, and then you want to use tempdata. Look here for reference: http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications

Resources