Serverless Authentication
This project is aimed to be a generic authentication boilerplate for the Serverless framework.
This boilerplate is compatible with the Serverless v.1.30.3+, to install Serverless framework run npm install -g serverless.
Web app demo that uses this boilerplate: http://laardee.github.io/serverless-authentication-gh-pages
If you are using Serverless framework v.0.5, see branch https://github.com/laardee/serverless-authentication-boilerplate/tree/serverless-0.5
Installation
The installation will create one DynamoDB table for OAuth state and refresh tokens.
- Run 
serverless install --url https://github.com/laardee/serverless-authentication-boilerplate, clone or download the repository - Change directory to 
authenticationand rename example.env.yml in authentication to env.yml and set environmental variables. - Run 
npm install. - Run 
serverless deployon the authentication folder to deploy authentication service to AWS. - (optional) Change directory to 
../test-tokenand runserverless deployto deploy test-token service. 
If you wish to change the cache db name, change CACHE_DB_NAME  in .env file and TableName in serverless.yml in Dynamo resource.
Set up Authentication Provider Application Settings
The redirect URI that needs to be defined in OAuth provider's application settings is the callback endpoint of the API. For example, if you use facebook login, the redirect URI is https://API-ID.execute-api.us-east-1.amazonaws.com/dev/authentication/callback/facebook and for google https://API-ID.execute-api.us-east-1.amazonaws.com/dev/authentication/callback/google.
If you have a domain that you can use, the configuration is explained in the custom domain name section.
Services
In this example project authentication and authorization services are separated from the content API (test-token).
Authentication
Authentication service and authorization function for content API. These can also be separated if needed.
Functions:
- authentication/signin
- endpoint: /authentication/signin/{provider}, redirects to oauth provider login page
 - handler: signin function creates redirect url to oauth provider and saves 
stateto DynamoDB 
 - authentication/callback
- endpoint: /authentication/callback/{provider}, redirects back to client webapp with token url parameter
 - handler: function is called by oauth provider with 
codeandstateparameters and it creates authorization and refresh tokens 
 - authentication/refresh
- endpoint: /authentication/refresh/{refresh_token}, returns new authentication token and refresh token
 - handler: function revokes refresh token
 
 - authentication/authorize
- endpoint: no endpoint
 - handler: is used by Api Gateway custom authorizer
 
 
Test-token
Simulates content API.
Functions:
- test-token/test-token
- endpoint: /test-token
 - handler: test-token function can be used to test custom authorizer, it returns principalId of custom authorizer policy. It is mapped as the username in request template.
 
 
Environmental Variables
Open authentication/env.yml, fill in what you use and other ones can be deleted.
dev:
# General
  SERVICE: ${self:service}
  STAGE: ${opt:stage, self:provider.stage}
  REGION: ${opt:region, self:provider.region}
  REDIRECT_CLIENT_URI: http://127.0.0.1:3000/
# Custom Redirect Domain
# REDIRECT_DOMAIN_NAME: ${opt:stage, self:provider.stage}.my-custom-domain-for-callback.com
# REDIRECT_CERTIFICATE_ARN: arn:aws:acm:us-east-1:111122223333:certificate/fb1b9770-a305-495d-aefb-27e5e101ff3
# REDIRECT_URI: https://${self:provider.environment.REDIRECT_DOMAIN_NAME}/authentication/callback/{provider}
# REDIRECT_HOSTED_ZONE_ID: XXXXXXXX
  TOKEN_SECRET: token-secret-123
# Database
  FAUNADB_SECRET: SERVER_SECRET_FOR_YOUR_FAUNADB_DATABASE
  CACHE_DB_NAME: ${self:service}-cache-${opt:stage, self:provider.stage}
  USERS_DB_NAME: ${self:service}-users-${opt:stage, self:provider.stage}
# Cognito
  USER_POOL_ID: user-pool-id
# Providers
  PROVIDER_FACEBOOK_ID: "fb-mock-id"
  PROVIDER_FACEBOOK_SECRET: "fb-mock-secret"
  PROVIDER_GOOGLE_ID: "g-mock-id"
  PROVIDER_GOOGLE_SECRET: "cg-mock-secret"
  PROVIDER_MICROSOFT_ID: "ms-mock-id"
  PROVIDER_MICROSOFT_SECRET: "ms-mock-secret"
  PROVIDER_CUSTOM_GOOGLE_ID: "cg-mock-id"
  PROVIDER_CUSTOM_GOOGLE_SECRET: "cg-mock-secret"
Example Provider Packages
- facebook serverless-authentication-facebook
 - google serverless-authentication-google
 - windows live serverless-authentication-microsoft
 - more to come
 
Custom Provider
Package contains example /authentication/lib/custom-google.js how to implement a custom authentication provider using generic Provider class. To test custom provider go to http://laardee.github.io/serverless-authentication-gh-pages and click 'custom-google' button.
User database
To use FaunaDB to save user data. First create a database here, then:
- configure 
FAUNADB_SECRETinauthentication/env.ymlwith a server secret for your database - uncomment 
return faunaUser.saveUser(profile);fromauthentication/lib/storage/usersStorage.js - change the last line of  
authentication/lib/storage/cacheStorage.jstomodule.exports = faunaCache; - Run 
STAGE=dev npm run setup:fauna 
To use DynamoBD to save user data:
- uncomment 
UsersTableblock fromauthentication/serverless.ymlresources - uncomment 
return dynamoUser.saveUser(profile);fromauthentication/lib/storage/usersStorage.js 
To use Cognito User Pool as user database:
- create new user pool (http://docs.aws.amazon.com/cognito/latest/developerguide/setting-up-cognito-user-identity-pools.html)
 - copy user pool id to 
authentication/env.yml - uncomment 
return saveCognito(profile);fromauthentication/lib/storage/usersStorage.js 
API Gateway Custom Domain Name
If you have a domain, a hosted zone, and a certificate for the domain defined in your AWS account, you may use API Gateway Custom Domain Name in your setup.
Your domain name goes to the REDIRECT_DOMAIN_NAME environment variable, if this is set, CloudFormation will create a custom domain name to API Gateway and recordset to the Route 53
REDIRECT_DOMAIN_NAME: "authentication.my-domain.com"
Certificate ARN for your domain,
REDIRECT_CERTIFICATE_ARN: "arn:aws:acm:us-east-1:111122223333:certificate/fb1b9770-a305-495d-aefb-27e5e101ff3"
Callback path, leave this like it is
REDIRECT_URI: "https://${self:provider.environment.REDIRECT_DOMAIN_NAME}/authentication/callback/{provider}"
Route 53 hosted zone id, go to Route 53 and get the id from there or with CLI aws route53 list-hosted-zones --query 'HostedZones[*].[Name,Id]' --output text. The CLI will output something like this authentication.my-domain.com.     /hostedzone/Z10QEETUEETUAO copy the Z10QEETUEETUAO part to the REDIRECT_HOSTED_ZONE_ID environment variable.
REDIRECT_HOSTED_ZONE_ID: "Z10QEETUEETUAO"
Running Tests
- Run 
npm installin project root directory - Run 
npm test