Facebook login with Parse client site, use user object with Express js - javascript

I am trying to create a login procedure with the Parse and Facebook Javascript SDK. The authentication works without a problem on the client side, but I need to access the user object (created by Parse SDK) on the server side too. How can I do this the most elegant way? I thought when I log in into Facebook via Parse a cookie is set and so I can access the user object from the server. Or should I do the login process server side? Any recommendations?

I'm facing the same problem. Turns out that you can use either server-side auth or client-side auth. You cannot mix-and-match the two. Have a look at their official blog post about sessions.
var parseExpressCookieSession = require('parse-express-cookie-session');
// In your middleware setup...
app.use(express.cookieParser('YOUR_SIGNING_SECRET'));
app.use(parseExpressCookieSession({ cookie: { maxAge: 3600000 } }));
// Making a "login" endpoint is SOOOOOOOO easy.
app.post("/login", function(req, res) {
Parse.User.logIn(req.body.username, req.body.password).then(function() {
// Login succeeded, redirect to homepage.
// parseExpressCookieSession will automatically set cookie.
res.redirect('/');
},
function(error) {
// Login failed, redirect back to login form.
res.redirect("/login");
});
});
Also, I came across this when digging through the doc:
You can add Parse.User authentication and session management to your
Express app using the parseExpressCookieSession middleware. You just
need to call Parse.User.logIn() in Cloud Code, and this middleware
will automatically manage the user session for you.
You can use a web form to ask for the user's login credentials, and
log in the user in Cloud Code when you receive data from this form.
After you call Parse.User.logIn(), this middleware will automatically
set a cookie in the user's browser. During subsequent HTTP requests
from the same browser, this middleware will use this cookie to
automatically set the current user in Cloud Code.
...
When you work with user data, you should use HTTPS whenever possible.
To protect your app and your users, the parseExpressCookieSession
middleware requires you to use HTTPS. For your convenience, we also
provide a parseExpressHttpsRedirect middleware for redirecting all
HTTP requests to HTTPS.

Related

Add Request Variable from Client to NodeJS Server for MiddleWare Router

I am trying to use routes to help server pages from a nodejs server based on a user being logged in. I am trying to take the login session details from the client side, and pass them back to the NodeJS server to be used in a middleware function for checking authentication.
How do I go about adding a variable to a request for a NodeJS route from the client side?
middleware.js
function loginRequired(req, res, next) {
if (!req.user) {
return res.status(401).render("unauthenticated");
}
next();
}
module.exports = { loginRequired };
server.js
app.use("/dashboard", middleware.loginRequired, mainPage);
The desired result would be, user clicks "Login", some variables are sent back, as well as the request to that route, the variables (i.e req.user) are used to check authentication.
You can send the variables in cookies, and use cookie parser, before your middleware. It provides parsed cookies.
For example, you can send a User variable in cookie, and then in your middleware use req.cookies which will contain your User variable.
Alternatively, you can send data in a POST request and use body-parser to do the same thing. But for authentication purpose, you should use cookies.

serverside rendering with no client-side javascript

I am trying to create an application that can post data both through ajax and through traditional form requests. I am surprised by the lack of information I am finding online about the topic. I guess these days we all assume we have access to client side JS?
I went with express-session, but am getting frustrated at how hard it is to determine what's actually happening. From what I can understand it's cacheing cookie data on the client and somehow including those in requests automatically? Then is it safe to assume that this format will NOT work without client-side javascript support?
Given a form like this:
<form method="post" action="/create">
<input name="value1" onChange={this.handleInput} value={this.state.value1} />
<button onClick={this.submitForm}
</form>
My requests sent via ajax will pass auth (due to having session data):
event.preventDefault();
postUrl(`/create`, {value1: this.state.value1})
.then(jsonRes => {
// works
});
being picked up by auth middleware which uses express session and passport:
module.exports.secured = (loginUrl = "/employers") => {
return (req, res, next) => {
if ( (req.isAuthenticated()) ) { return next(); }
req.session.returnTo = req.originalUrl;
res.redirect(loginUrl);
return next();
};
};
which protect a pretty simple api route for creating:
router.post('/create', secured(), (req, res) => {
My thinking is that even if JS is enabled, I could handle the request at this route, but the problem is with authenticating.
What can I do to get my session data sent over in these 'non-js' requests?
I remember in traditional webstacks like Rails or PHP some sort of token is rendered into the form in a hidden field or in the action on render. If this would work, does anyone know how to get the 'vital data' so to speak out of the express session to send as the token? Not possible?
Looking in req.cookies or req.session of the req object that gets parsed in the serverside render, I do not see anything that would be useful for this.
What can I do to get my session data sent over in these 'non-js' requests?
Ussually the response to your login would send a Set-Cookie header to indicate to the client that it should store said cookie, implying it would be used to identify himself
Who stores cookies? its not javascript but the browser, so if you used curl or a scraper , your clients would have to fetch the cookie returned and include it in subsequent requests
What you mention about a token in the form is not for authentication but for cross site request forgery, meaning that since you served a token (and stored it somehow server side) you would only accept a login request including said token (proving someone navigated to your site's login page) so as to prevent other websites or clients who didnt went to your login to attempt POSTing (ie: a scraper )
Also, sessions dont necessarily mean authentication, modern frameworks tend to issue a session regardless if authenticated

Issue in binding social accounts with local account in web app

App description:
User can sign up with credentials and get authorization and refresh token from a server, they're saved respectively in session and local storage. Axios is configured to intercept 401 status response and then make a new request to separete endpoint with refresh token as a payload. Server verify refresh token and respond with new authorization token that is set as a default header to every axios request. User can also login with social accounts (fb, g+, github) which are implemented using passport lib.
Task description:
As a logged user I can connect my current account with my social account. This case is included in passport documentation.
Problem description:
Requests to route specified in documentation:
app.get('/connect/twitter',
passport.authorize('twitter-authz', { failureRedirect: '/account' })
);
can be done only by redirection with <a href='/connect/twitter'>,
XMLHttpRequest is not possible due to CORS error (eg. example). And this is a problem, I can't send auth token using simple redirection so server can't decode token and get local user info and so can't add updated user data (with social account data) to database..
Source code
Http address
PS. Sorry for bad english, I will appreciate any help!

What is the best way to access the JWT from node?

I have implemented JWT authentication using Node.js. When the user signs in, Node.js signs/creates a JWT and sends it back. Thereafter, it is stored in the localStorage. Now, this is probably where I am going wrong, but... to move forward, I make use of the express router, and within the router code (which is obviously at the node level) I want to be able to access the token (which is in localStorage) so that I can make a call to the API for further data. However, I just realised that localStorage is at the client-end and that node/express/router doesn't recognise localStorage. So I am stuck. Obviously, I am doing something fundamentally wrong... I should not need to access localStorage from the express router file. Perhaps, I should really be making the API calls not from the express router file, but from client side.
Any hints/directions?
localstorage is bad way to save token. you should save token in cookies and use then where you want.
EXAMPLE:
new Cookies(req,res).set('access_token',token,{
httpOnly: true,
secure: true // for your production environment
});
and then read:
var token = new Cookies(req,res).get('access_token');
You need to send the JWT that is stored on the client side every time you make an API request to the server side.
https://jwt.io/introduction/
Scroll down to the section How do JSON Web Tokens work? The JWT should be sent in the header of the API calls in the form:
Authorization: Bearer <token>
How you do this depends on how exactly you'll send the HTTP requests to the API, but it should be pretty simple in any respects. You can find out about how to add Headers to an angular $http request at this link:
https://docs.angularjs.org/api/ng/service/$http
Then it's up for each of your authenticated express routes to check the headers, pull the JWT out, ensure that it's valid, and then proceed with the request (or halt it if the JWT is invalid).

Disabling sessions in nodejs Passport.js

I just discovered about Tokens for authentication which allows session/stateless servers and starting out with MEAN. Looks amazing.
Right now, I'm using Passport.js to authenticate users (via Email, Facebook, Google,...), which stores information into the server session like all the tutorials say:
// required for passport
app.use(express.session({
secret : 'superscret',
expires: new Date(+new Date + settings.session.sessionTimeout),
store: new MongoStore({})
})); // session secret
app.use(passport.initialize());
app.use(passport.session({}));
Is it possible to still use Passport.js but instead of storing the session, sends back a token to monitor if the user has access.
Question: How can disable sessions for passport? (I know how to send the token and listen for it).
I suggest using satellizer, de-facto standard library for token based authentication in AngularJS. It implements token based authentication only and is much easier to get working for your purposes. It also has good server examples, including Node.js server example.
passportjs supports disabling of the sessions. Docs passport
After successful authentication, Passport will establish a persistent login session. This is useful for the common scenario of users accessing a web application via a browser. However, in some cases, session support is not necessary. For example, API servers typically require credentials to be supplied with each request. When this is the case, session support can be safely disabled by setting the session option to false.
app.get('/api/users/me',
passport.authenticate('basic', { session: false }),
function(req, res) {
res.json({ id: req.user.id, username: req.user.username });
});

Categories

Resources