├── .gitignore ├── README.md ├── package.json ├── handler.js ├── serverless.yml └── authorizer.js /.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serverless HTTP Basic Auth 2 | 3 | Example of HTTP Basic Authentication setup in API Gateway and Serverless 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slstest", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = (event, context, callback) => { 4 | const response = { 5 | statusCode: 200, 6 | body: JSON.stringify({ 7 | message: 'Go Serverless v1.0! Your function executed successfully!', 8 | input: event, 9 | }), 10 | }; 11 | 12 | callback(null, response); 13 | }; 14 | -------------------------------------------------------------------------------- /serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-nodejs 2 | 3 | provider: 4 | name: aws 5 | runtime: nodejs6.10 6 | 7 | functions: 8 | hello: 9 | handler: handler.hello 10 | events: 11 | - http: 12 | path: /hi 13 | method: get 14 | authorizer: 15 | name: authorizer 16 | resultTtlInSeconds: 0 17 | identitySource: method.request.header.Authorization 18 | type: request 19 | authorizer: 20 | handler: authorizer.handler 21 | 22 | 23 | resources: 24 | Resources: 25 | GatewayResponse: 26 | Type: 'AWS::ApiGateway::GatewayResponse' 27 | Properties: 28 | ResponseParameters: 29 | gatewayresponse.header.WWW-Authenticate: "'Basic'" 30 | ResponseType: UNAUTHORIZED 31 | RestApiId: 32 | Ref: 'ApiGatewayRestApi' 33 | StatusCode: '401' 34 | -------------------------------------------------------------------------------- /authorizer.js: -------------------------------------------------------------------------------- 1 | exports.handler = function (event, context, callback) { 2 | var authorizationHeader = event.headers.Authorization 3 | 4 | if (!authorizationHeader) return callback('Unauthorized') 5 | 6 | var encodedCreds = authorizationHeader.split(' ')[1] 7 | var plainCreds = (new Buffer(encodedCreds, 'base64')).toString().split(':') 8 | var username = plainCreds[0] 9 | var password = plainCreds[1] 10 | 11 | if (!(username === 'admin' && password === 'secret')) return callback('Unauthorized') 12 | 13 | var authResponse = buildAllowAllPolicy(event, username) 14 | 15 | callback(null, authResponse) 16 | } 17 | 18 | function buildAllowAllPolicy (event, principalId) { 19 | var apiOptions = {} 20 | var tmp = event.methodArn.split(':') 21 | var apiGatewayArnTmp = tmp[5].split('/') 22 | var awsAccountId = tmp[4] 23 | var awsRegion = tmp[3] 24 | var restApiId = apiGatewayArnTmp[0] 25 | var stage = apiGatewayArnTmp[1] 26 | var apiArn = 'arn:aws:execute-api:' + awsRegion + ':' + awsAccountId + ':' + 27 | restApiId + '/' + stage + '/*/*' 28 | const policy = { 29 | principalId: principalId, 30 | policyDocument: { 31 | Version: '2012-10-17', 32 | Statement: [ 33 | { 34 | Action: 'execute-api:Invoke', 35 | Effect: 'Allow', 36 | Resource: [apiArn] 37 | } 38 | ] 39 | } 40 | } 41 | return policy 42 | } 43 | 44 | --------------------------------------------------------------------------------