Raj Bhatia
Raj Bhatia

Reputation: 1108

Node express server not rendering static content using aws lambda for angular app

I'm newly trying to deploy angular application on AWS lambda, but getting exception 403 for my static content. I'm using express js to configure server. Please visit and inspect this [AWS lambda URL] https://www.mypleaks.com where i'm facing this issue.

this is the server.ts file

    import 'zone.js/dist/zone-node';
    import { join } from 'path';
    import * as express from 'express';
    import { AppServerModule } from './src/main.server';
    import { APP_BASE_HREF } from '@angular/common';
    import { ngExpressEngine } from '@nguniversal/express-engine';
    import { existsSync } from 'fs';

    // Express server
    export const app = express();

    const PORT = process.env.PORT || 4000;
    const DIST_FOLDER = join(process.cwd(), 'dist/myPleaks/browser');
    const indexHtml = existsSync(join(DIST_FOLDER, 'index.original.html')) ? 'index.original.html' : 'index';

    // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
    app.engine('html', ngExpressEngine({
        bootstrap: AppServerModule,
    }));

    app.set('view engine', 'html');
    app.set('views', DIST_FOLDER);

    // Example Express Rest API endpoints
    // app.get('/api/**', (req, res) => { });
    // Serve static files from /browser
    app.get('*.*', express.static(DIST_FOLDER, {
      maxAge: '1y'
    }));

    // All regular routes use the Universal engine
    app.get('*', (req, res) => {
      res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
    });

and here lambda.js

    const awsServerlessExpress = require('aws-serverless-express');
    const server = require('./dist/myPleaks/server/main');
    const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware');
    const binaryMimeTypes = [
        'application/javascript',
        'application/json',
        'application/octet-stream',
        'application/xml',
        'image/jpeg',
        'image/png',
        'image/gif',
        'text/comma-separated-values',
        'text/css',
        'text/html',
        'text/javascript',
        'text/plain',
        'text/text',
        'text/xml',
        'image/x-icon',
        'image/svg+xml',
        'application/x-font-ttf',
        'font/ttf',
        'font/otf',
    ];

    server.app.use(awsServerlessExpressMiddleware.eventContext());
    const serverProxy = awsServerlessExpress.createServer(server.app, null, binaryMimeTypes);
    module.exports.handler = (event, context) => { awsServerlessExpress.proxy(serverProxy, event, context) }

and here serverless.yml

      service: mypleaks # Name whatever as you like!
  plugins:
    - serverless-apigw-binary
    - serverless-offline

  provider:
    name: aws
    runtime: nodejs10.x
    memorySize: 192
    timeout: 10
    stage: production
    region: ap-south-1

  package:
    exclude:
    - src/**
    - node_modules/**
    - firebug-lite/**
    - e2e/**
    - coverage/**
    - '!node_modules/aws-serverless-express/**'
    - '!node_modules/binary-case/**'
    - '!node_modules/type-is/**'
    - '!node_modules/media-typer/**'
    - '!node_modules/mime-types/**'
    - '!node_modules/mime-db/**'

  custom:
    contentCompression: 1024
    apigwBinary:
      types:
        - '*/*'

  functions:
    api:
      handler: lambda.handler
      events:
        - http: ANY /

Thanks in advance.

Upvotes: 1

Views: 1893

Answers (1)

Jon Church
Jon Church

Reputation: 2350

I think your problem is related to your serverless.yml. It's really frustrating because I can't find anywhere to point you to in the serverless docs, but I think your problem is that you are telling Lambda to respond to only one specific route, /.

If you load the resources directly in the browser that you're getting a 403 on, you'll see you're getting the error:

{"message":"Missing Authentication Token"}

Googling that message shows it's a lambda specific error.

Check out this example I found where they are adding another http event to accept requests at all paths:

- http:
          path: /{any+} # this matches any path, the token 'any' doesn't mean anything special
          method: ANY

Upvotes: 2

Related Questions