How to serve protected pages with Express and node - javascript

New to web development so sorry for the (probably) dumb question
I am building a web app which will need user accounts and verification. I would like to serve several pages (one of which is calendar.html) only if the user is logged in. I created an express endpoint /calendar which will successfully load the page using either ejs or sendFile, but only when the get request is recieved via a URL redirect:
response.render('calendar.ejs')
response.sendFile(path.join(__dirname, '/public/calendar.html'))
The problem is, with a URL redirect eg window.location.href = calendar (I may be wrong here) I cannot send additional information like the user's email address or authentication key in the request header. I would also like to have clean URLs and not encode this data into the URL.
I know how to send these data in a get request using fetch(), however if I do that, the page does not render using either of the above methods. How can I send the credentials to the server, serve back calendar.html and display it, all with a clean URL?

Related

Securely pass current wordpress user to external flask app

I have a Wordpress site with users, and a separate Flask app with logic for responding to Get/Post requests from the WordPress site.
I am able to get the current user into a JavaScript variable on the WP site and send to the Flask app - however how do I ensure that someone cannot pretend to be a different current user, or make this secure to other potential vulnerabilities?
Is there some way of exposing a token or suchlike to JavaScript on the WP side, which then the Flask app can verify, say by using the WordPress API?
We would likely need a little bit more detail to be sure the best way to solve, but it seems there are a few ways of approaching this.
You've said that you can get the user id into JavaScript. I'm presuming this means the browser is needing to make the connection to the Flask app. If you have the option of doing this with the WordPress site calling the Flask app directly (server-to-server) you can avoid a lot of hassle.
If you are able to send the request directly from the WordPress server to the Flask app, and the Flask app can check that the source of the request is the WordPress site (either by a shared secret, by checking the IP address the request came from, or just by filtering the traffic to the Flask app to only permit the WordPress server) then do that and you can be sure of the identity of the user making the request.
But if the request has to be made to the Flask app from the browser, then you could do this in a couple of general ways:
Encrypt the value from WP to Flask -- Create a shared secret on the server(s) which is used to encrypt or sign the user id. The WP site would generate the encrypted/signed version of the user id and send that to the browser. The browser javascript code would send this to the Flask app, which would (knowing the shared secret) decrypt the id or verify the signature. This is the simpliest method.
Use an opaque ID -- Generate a random number in the server-side code of the WP site, and record the user id that it was generated for. Send the random number to the browser, which sends it on to the Flask app. Flask then asks WordPress what the user id associated with that random number is.
You need to send the data directly from backend side, but if it depends on a frontend trigger, you can then send an AJAX request from JavaScript to backend in WP side.
jQuery.post( admin_ajax_url, { action: 'get_current_user' } );
and without the nopriv, This function will be triggered only for logged in users.
add_action( 'wp_ajax_get_current_user', 'ajax_get_current_user' );
inside the function, you can get the current user WP_User object and the user ID.
function ajax_get_current_user() {
$current_user_object = wp_get_current_user();
$current_user_id = get_current_user_id();
// Send the User details to flash App here...
}
This is a quick walkthrough of how it should be done. sure, AJAX request will need a nonce check, and sanitization for any passed data, etc.
More details about AJAX request in WP
https://developer.wordpress.org/plugins/javascript/ajax/
https://developer.wordpress.org/plugins/javascript/enqueuing/
https://jackreichert.com/2013/03/24/using-ajax-in-wordpress-development-the-quickstart-guide/
and the WP HTTP API for sending the data to the flask app
https://developer.wordpress.org/plugins/http-api/
You need WordPress Application Passwords. It's essentially a password for APIs.
In your case, you need to define the application password of the WordPress user in Flask, then Flask can send requests to the WordPress REST API as an authenticated user.

NodeJS - Session handling WITHOUT express

I have built my app, I used plain JS on NodeJS and it is a single-page app. I didn't use express.
First the user needs to log in. The login-data is sent via websocket to the server and there the credentials are checked against a MySql-DB. If they are correct, the loggedIn-content is generated and sent back to the client, where it is displayed.
Now when a user is already logged in, and then refreshes the browser, he lands on the initial state of the app, and needs to log in again.
how can I fix this?
I read a lot about session-handling in NodeJS, but most articles include express, which confuses me to understand this whole concept.
HTTP itself is stateless, so you need some sort of way to identify the user.
Traditionally, this is done via cookies. When you respond to an HTTP request, you include a cookie in your response headers. For all subsequent HTTP requests, the client will include this cookie information back to you.
This means that you can send some sort of session identifier, and for all future requests you can look up the session data. The conversation goes a bit like this.
Client: Here's my login information, and I'd like the home page.
Server: Ok, thanks. Here's the home page. Also, remember that your session ID is 12345. Next time you ask me for something, tell me that session ID. (Logs in the database that session ID 12345 is associated with someuser.)
Then later...
Client: I'd like this other page. You told me to tell you that my session ID is 12345.
Server: (Loads session information for 12345, sees that it's associated with someuser.) Ok, here's that other page.
How you actually do the storage of all that is up to you. Many folks use databases, since they're often already using them for the application and it makes it easy to share session data with multiple instances of the application server.

Nodejs to redirect to different URL with Form Submit

When I do a post to a backend service and get a 307 in my response, I'm doing a res.redirect('/'). Instead of doing that, can I redirect to a URL that belongs to a completely different site as well as post a form submit to that URL? I want to send values for SAML and RelayState. I currently have this login in my frontEnd by temporarily adding into the DOM a hidden form with two inputs. One for SAML and one for RelayState. Would it be possible to take that out of the frontend and have it done completely in the backend?
If i'm understanding this thread correctly, I'd like to do something like this but be able to dynamically fill in values for the inputs. The index.html example in this thread is essentially what i'm doing on the fly on my frontend:
How to redirect to another page after serving a post request in Node.js?
EDIT:
Nevermind, I will do the submit on the frontend. When the other service returns a redirect, nothing will happen if I'm on my backend.

How to secure web pages with token based authentication?

I'm building a website using ruby on rails which is hosted separately which makes requests to another backend api rails app which is again hosted separately. Obviously i've setup the backend api with token based oauth authentication.
Now since im not dealing with sessions, and it being stateless n all, How can I stop users from accessing certain view pages in my front end web app? For example, I have a consumer/booking page. I don't want the user to access this page without being logged in. But anyone can just enter the url and open any page they want right now.
On user login (ajax call from .js.erb files), im getting the token and storing it in localStorage variable for every future request to the api. I know I should use this token somehow to stop users from access restricted pages. But I just dont know how.
Now as you have stored the token in the localStorage, you will need to pass this token with the request to the page where you want to restrict access and check if the user is authorized to access the page or not.
TL;DR: there is no standard method or library for this; you must implement such functionality as you see fit.
I'm assuming you're using some sort of front end framework like react; if so, then any request to change the current view should be terminated if there is no valid token in localStorage. Check out this post regarding conditional rendering in React; if you're using something else, the methodology is still pretty much the same.
Otherwise, I would build a small script to include in the beginning of every page that checks whether or not there is a valid token and if there isn't, calls window.history.back() to return the user to the previous page.
(Another way of doing it is to intercept every call to a static HTML file on the server, check if there's a token, and send the file if there is. Otherwise, you can send a custom error page or whatever).

Using Facebook API in widget

I'm building a widget that can be placed on a various sites, and will have users be able to log in via facebook connect to accounts on the widget's parent site. I was going to use the Facebook JS SDK to do this, but the widget will likely be placed on sites that already have the FB JS SDK initialized on them with a different app ID, and if I were to run code this way it could lead to a namespace problem.
The only current solution I have come up with is to do the server-side type authorization, and have a redirect-url that leads back to the current page in which the widget is hosted and use the state paremeter to alert backbone router that the user has logged in.
The first problem I thought of is that on the facebook docs site it says
For security, the redirect_uri must have the same base domain as that specified in the App Domain property of your app's settings, or be a URL of the form https://apps.facebook.com/YOUR_APP_NAMESPACE.
How do I bring people back to the original page that the widget it hosted on after login? Is there a better approach to this problem?
you can use Server side authentication and redirect_uri to your site that will redirect to the various site
redirect_uri = https://www.mydomain.com/?r=https%3A%2F%2Fwww.somesite.me
On you server you will look of the query param r and redirect the request to r value.
You can also do your own authentication for users (when they first sign in) and store there facebook access_token on you DB, once your widget is running (under https) and you identified the user on your authentication you can send the widget client the user's access_token and work with it.
You can even create your own Simple FB-like ajax library, for most things it will be a simple get/post/put calls with access_token as a url parameter
Hopes it helps

Categories

Resources