I am trying to use greenlock-express to test serving an app with ssl. I am following the documentation here:
So I have app.js:
"use strict";
// Here's a vanilla HTTP app to start,
// but feel free to replace it with Express, Koa, etc
var app = function (req, res) {
res.end("Hello, Encrypted World!");
};
module.exports = app;
And I have server.js:
"use strict";
var app = require("./app.js");
require("greenlock-express")
.init({
packageRoot: __dirname,
// contact for security and critical bug notices
maintainerEmail: "my_email#gmail.com",
// contact for security and critical bug notices
configDir: "./greenlock.d",
// whether or not to run at cloudscale
cluster: false,
})
// Serves on 80 and 443
// Get's SSL certificates magically!
.serve(app);
I used this command:
npx greenlock init --config-dir ./greenlock.d --maintainer-email
'my_email#gmail.com'
And this command:
npx greenlock add --subject my_website.online --altnames my_website.online
That generated the greenlock.d folder:
config.json
{
"defaults": {
"store": {
"module": "greenlock-store-fs"
},
"challenges": {
"http-01": {
"module": "acme-http-01-standalone"
}
},
"renewOffset": "-45d",
"renewStagger": "3d",
"accountKeyType": "EC-P256",
"serverKeyType": "RSA-2048",
"subscriberEmail": "my_email#gmail.com"
},
"sites": [
{
"subject": "my_website.online",
"altnames": [
"my_website.online",
"www.my_website.online"
],
"renewAt": 1
}
]
}
After I run the app on my VPS, this is what gets logged:
However, when I try to access the app, this is what I see:
I followed the exact steps in the tutorial so I do not see why this doesn't work.
Any thoughts?
Related
I have a Firebase + Cloud Function API + Express API with the following files:
/functions/index.js
const functions = require('firebase-functions');
const express = require('express');
const app = express();
app.get('/api/echo', (req, res) => {
res.status(200).json({
message: req.query.message,
});
});
exports.api = functions.https.onRequest(app);
/firebase.json
{
"hosting": {
"rewrites": [
{
"source": "/api/**",
"function": "api",
"region": "us-central1"
}
]
},
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
]
}
]
}
To test the app on LOCAL I run the following command:
$ firebase emulators:start --inspect-functions
To access the endpoint on LOCAL I go to the following url:
[1] http://localhost:5001/[my-project]/us-central1/api/api/echo/?message=Hello+World
To deploy the app to Firebase (REMOTE) I run the following command:
$ firebase deploy --only hosting,functions
To access the endpoint with Google domain I go to the following url:
[2] https://us-central1-[my-project].cloudfunctions.net/api/api/echo/?message=Hello+World
To access the endpoint with my custom domain I go to the following url:
[3] https://www.[mydomain.tld]/api/echo/?message=Hello+World
With all 3 urls above I get the following (expected) output:
{"message":"Hello World"}
My problem is: On urls: [1] and [2] I need to specify /api twice (please check above). I would like to configure things around in order to just need to specify: /api once on urls: [1], [2], [3]. It doesn't look good to me having to specify: /api twice.
It is a requirement for me to access the endpoints after: /api/ because on the parent level I have a web app that uses the endpoints.
Any idea on how to do this?
Thanks!
I'm using Firebase Functions, and Firebase Hosting. Hosting redirects all traffic to my function.
Request cookies are not available when requesting the Hosted site (i.e. not the cloud function URL). Is there no way to access request cookies?
I'm migrating a website to Firebase and was assuming I could follow basic web principals of having access to same-domain cookies.
const { runWith } = require('firebase-functions');
const cookieParser = require('cookie-parser');
const express = require('express');
const app = express();
app.use(cookieParser());
function handleRequest(req, res) {
res.cookie('firebase1', 'test', {});
if (process.env.HOSTNAME) {
res.cookie('firebase2', 'test', {
domain: process.env.HOSTNAME,
});
}
res.cookie('firebase3', 'test', {
domain: req.hostname,
});
return res.json({
hostname: process.env.HOSTNAME,
'req.cookies': req.cookies, // always empty
'req.headers.cookie': req.headers.cookie, // always undefined
});
}
app.get('*', handleRequest);
app.use(handleRequest);
exports.index = runWith({
timeoutSeconds: 10,
memory: '128MB',
}).https.onRequest(app);
firebase.json
{
"functions": {
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
]
},
"hosting": {
"public": "public",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"function": "index"
}
]
}
}
Answer from Firebase's support team:
When using Firebase Hosting together with Cloud Functions or Cloud Run, cookies are generally stripped from incoming requests. This is necessary to allow for efficient CDN cache behavior. Only the specially-named __session cookie is permitted to pass through to the execution of your app.
When present, the __session cookie is automatically made a part of the cache key, meaning that it's impossible for two users with different cookies to receive the other's cached response. Only use the __session cookie if your app serves different content depending on user authorization. Also, you need to set the Cache-Control Header as private res.setHeader('Cache-Control', 'private').
I haven't tested it but the Express API doc indicates that, since you use the cookie-parser middleware, you should do req.cookies and not req.headers.cookie
I've implemented an express server that uses express.static to serve the build folder created from a static docusaurus site in order to apply basic authentication to access the site. This is working great locally, but I'm running into troubles when deploying to Vercel.
Currently my configuration is allowing the deployed version on vercel to render the basic auth login page, but upon successful login I am directed to a page the states: "Cannot GET /"
I belive this is likely an issue with either my vercel.json configuration, or with my vercel's template settings.
My code is as follows:
index.mjs
import express from 'express';
import dotenv from 'dotenv';
dotenv.config();
const app = express();
app.use(express.json());
const authorize = ((req, res, next) => {
const auth = {login: process.env.USERNAME, password: process.env.PASSWORD}
const b64auth = (req.headers.authorization || '').split(' ')[1] || ''
const [login, password] = Buffer.from(b64auth, 'base64').toString().split(':')
if (login && password && login === auth.login && password === auth.password) {
return next()
}
res.set('WWW-Authenticate', 'Basic realm="401"')
res.status(401).send('Authentication required.')
});
app.use('/', authorize);
app.use('/', express.static('build'));
app.listen(3000);
console.log(`🚀 Server ready at http://localhost:3000`);
vercel.json
{
"version": 2,
"builds": [{
"src": "./index.mjs",
"use": "#vercel/node"
}],
"routes": [{"handle": "filesystem"},
{
"src": "/.*",
"dest": "/"
}
]
}
package.json - start script
"start": "node --experimental-modules index.mjs",
And my vercel template is set to other, with the start script set to npm start.
Any ideas would be greatly appreciated!
I had similar issue: serve some static content and use /api routes. All worked fine in local dev but throwed "Cannot GET/" in vercel.
My solution.
Build separately serverless and static content.
Route adjustements for /api calls and static content.
My final vercel.json:
{
"version": 2,
"builds": [
{
"src": "server.js",
"use": "#vercel/node"
},
{
"src": "public/**",
"use": "#vercel/static"
}
],
"routes":[
{
"src": "/api/(.*)",
"dest": "server.js"
},
{
"src": "/",
"dest": "public/index.html"
},
{
"src": "/(.+)",
"dest": "public/$1"
}
]
}
Notes
All static content is under /public (html,css,img,js,etc)
server.js is the main app: express and route definitions. Similar to yours.
vercel build log shows:
Generated build outputs:
12:28:55.974 - Static files: 12
12:28:55.974 - Serverless Functions: 1
12:28:55.975 - Edge Functions: 0
...
12:28:58.142 Done with "server.js"
Maybe from this point you can find a solution for your case.
Ok, I've been looking for a solution for this one a little, and turns out we have to serve index.html explicitly in express:
app.get('/', (req: Request, res: Response) => {
res.sendFile('index.html', {root: path.join(__dirname, 'public')});
});
given that you probably have index.html in public folder. That's what solved the issue for me.
I have built a react app webpage, i use node, express and react. I serve it within an ec2 ubuntu server with nginx, i also installed ssl and configured DNS but when I load the page, the first time it gives no problems, but when reloaded, i get this Server responded with 429 status code
The page is very simple itself, but stills failing and i can't solve the problem, i have read a lot of posts and blogs to fix it but none has worked (this only happens in production, in dev environment i get no error when running my node app).
Some of those said that you had to lazy load images and i did it, i have also tried loading components in timeout so requests are made every 1.5 seconds...
The main files that give me problems are the manifest.json and favicon.ico, they are accesible by url so i can't understand why (another 429 example).
Node server.js
Routes has nothing, just console logs
require('dotenv').config();
const express = require("express");
const app = express();
const path = require("path");
const cors = require("cors");
const allowedOrigins = [`http://localhost:${process.env.PORT}`];
var corsOptions = {
origin: function (origin, callback) {
if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
};
app.use(cors(corsOptions));
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(express.static(path.join(__dirname, "/public")));
app.use("/", require("./routes/routes"));
app.get("*", (_, res) => res.redirect("/"))
app.listen(process.env.PORT, function () {
console.log(`Listening on port ${process.env.PORT}`);
});
App directory structure
This is my folders structure, public folder is the build that react script npm run build returns.
React app directory structure
Here you can see the structure, nothing special to what you get when run npx create-react-app. As you can see, there's a favicon.ico and manifest.json.
Manifest.json
{
"short_name": "Proximedica BajÃo",
"name": "Proximedica BajÃo - OxÃgeno Medicinal",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
This is all, if you need me to provide some other file it would be a pleasure.
Thanks!
Hi I have some architecture, My front end application I have built using grunt,it running on localhost:3000 nodejs server, My BackEnd Application are in the Apache tomcat server (localhost:8080) . Basically backend application running on spring framework. guys i want to send request from my localhost:3000 to localhost:8080 using gruntjs.
Pls help me.
This is my grunt js file
module.exports = function(grunt){
grunt.initConfig({
concat: {
options: {
separator : '\n\n//--------------------------------------------------\n\n;',
banner : '\n\n//---------------All Js file is here ---------------\n\n'
},
dist :{
src :['components/scripts/*.js'],
dest:'builds/development/js/scripts.js'
}
},
sass : {
dist :{
options:{
style:'expanded'
},
files:[{
src:'components/sass/style.scss',
dest:'builds/development/css/style.css'
}]
}
},
connect:{
server:{
options:{
hostname:'localhost',
port:'3000',
base:'builds/development/',
livereload:true
}
}
},
watch: {
scripts: {
files: ['builds/development/**/*.html',
'components/scripts/**/*.js',
'components/sass/**/*.scss'],
tasks: ['concat','sass'],
options: {
spawn: false,
livereload:true
},
},
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.registerTask('default',['concat','sass','connect','watch']);
};
To solve your problem you have to write separate node server and register with grunt task.
var http = require('http');
var httpProxy = require('http-proxy');
var server = http.createServer(function(){
httpProxy.createProxyServer({target: 'http://localhost:8080'}).web(req, res);
});
module.exports = function(grunt) {
grunt.registerTask('server', function() {
// this.async(); // run forever
server.listen(8000);// Front End Server Listening Port
});
};