简体   繁体   中英

How to force https for a React app deployed on Google App Engine node.js flex environment?

I want to force https connections for my React app deployed on Google App Engine node.js flexible environment. My React app was created with

npx create-react-app my-cool-app  

And I have an app.yaml placed in project root directory. The app.yaml contains the following:

env: flex
runtime: nodejs
service: frontend-staging

I have seen other questions/answers on here mention using the npm helmet library. But I don't understand how that applies to my case. Isn't Google App Engine serving a static build directory using nginx? There is no Express server here - just front end code. How can I set http security headers using this library if I just have front end code? Do I need to place an Express app server in between nginx and my React stuff?

Also I asked Google Support about modifying the nginx.conf file. But, according to them, I would have to SSH into the instance and modify the file that way. Well, what happens if the load on an instance increases and GAE automatically fires up another instance? Now I have to somehow detect that and manually SSH into that instance to fix the nginx.conf file? I saw that mentioned as a potential solution on here as well but this seems like a poor option.

Note: I don't think this is a duplicate. I am specifically asking how to implement the helmet library with nginx + Express + React + code examples for GAE node.js flex environment, not a higher level strategy question.

I finally figured this out on my own. You need to create an express server, run a "yarn build", and serve those static files generated by the "yarn build" script from the express server. So, I recommend configuring your directory structure like this:

appRoot 
    ->client
        ->create-react-app contents here 
    app.yaml 
    app.js 
    package.json 

Note that there are TWO package.json's in this config. One is inside the client folder, and is created as part of the setup when you run "create-react-app". The other is for your nodejs server application, and lives in the appRoot directory. Inside the app.js file is where you will place the code to serve your static React files:

const express = require('express');
const helmet = require('helmet')
const app = express();
const port = process.env.PORT || 3000;

const sixtyDaysInSeconds = 5184000
app.use(helmet.hsts({
   maxAge: sixtyDaysInSeconds
}))

//Serve up all of our static assets 
app.use( express.static('client/build') );

//Make all incoming GET requests return the index.html in order to take advantage of the client side router
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/client/build/index.html', function(err) {
    if (err) {
        res.status(500).send(err);
    }
   })
})

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

Make sure you add the "helmet" library to your dependencies by running

yarn add helmet 

And of course add express by running

yarn add express 

All your app.yaml needs to have is:

env: flex
runtime: nodejs
service: frontend-staging

Now deploy your app to GAE and you should be serving the HSTS headers along with every request. Note that serving HSTS headers does not redirect a user to https right away. From Mozilla Developer Network, "The first time your site is accessed using HTTPS and it returns the Strict-Transport-Security header, the browser records this information, so that future attempts to load the site using HTTP will automatically use HTTPS instead."

In other words, your user must attempt to access the site at least once using https in order for the HSTS header to be sent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM