Javascript Cloud Slideshare 140210053940 Phpapp02

download Javascript Cloud Slideshare 140210053940 Phpapp02

of 60

Transcript of Javascript Cloud Slideshare 140210053940 Phpapp02

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    1/60

    AngularJS & CloudCloudConf 2014 Gabriele Mittica

    www.corley.it

    http://www.corley.it/http://www.corley.it/
  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    2/60

    JavaScript & Cloud?

    Cloud based database and storage services are very p

    Why?

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    3/60

    The Cloud is

    Cheap for startup projects

    Ready to scale for growing projects

    Rich of services for complex projects

    How we can use the cloud with

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    4/60

    FrontEnd BackEnd

    HTML/JS REST PHP

    MySQL / Mongo

    HTTP

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    5/60

    HTML/JSSAWS

    CLOUD

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    6/60

    With AngularJS we can c

    apps that work with RE

    resources or directly with

    services.

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    7/60

    Next steps

    #1 - signup to AWS website

    #2 - access to the AWS Web console

    #3 - create a IAM user with access to all servic

    #4 - download and use the JavaScript SDK

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    8/60

    Introducing Amazon Web Servic

    Over 25 cloud based services available

    Several regions across the world

    JavaScript SDK available

    http://aws.amazon.con

    http://aws.amazon.con/http://aws.amazon.con/http://aws.amazon.con/
  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    9/60

    Signup to AWS on aws.amazon.com

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    10/60

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    11/60

    IAM: Identity and Access Managemen

    AWS Identity and Access Management (IAM) enables us to securely control

    to AWS services and resources for our users, setting users and groups and

    permissions to allow and deny their access to AWS resources.

    Backup

    system

    AW

    Sto

    AWEmail

    Marketing

    app

    PUT & GET

    FULL ACCESS

    YOUR APP AWS SAWS IAM

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    12/60

    We create an u

    users) with Pow

    level, in order to

    to all services.

    Then, we haveaccess and sec

    use with the JS

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    13/60

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    14/60

    Upload a file to Amazon Simple Storage Service with classic JS:

    Upload to S3

    var bucket = new AWS.S3({params: {Bucket: 'myBucket'}});var fileChooser = document.getElementById('file-chooser');var button = document.getElementById('upload-button');var results = document.getElementById('results');

    button.addEventListener('click', function() {var file = fileChooser.files[0];if (file) {results.innerHTML = '';var params = {Key: file.name, ContentType: file.type, Body: fbucket.putObject(params, function (err, data) {results.innerHTML = err ? 'ERROR!' : 'UPLOADED.';

    });}else {results.innerHTML = 'Nothing to upload.';

    }}, false);

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    15/60

    Thats all!

    Very Easy!

    The

    browser

    AWS

    Storage

    File uploaded

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    16/60

    Our keys (primarily the secret one) are exposed.

    Bad guys (backend developers?) could use our

    keys for malicious intents!

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    17/60

    Solutions:

    #1

    Use read-only

    IAM keys

    #2

    Ask user to write

    own keys

    #3

    Work w

    own bac

    Read-only

    appHard IAM

    management

    Targ

    miss

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    18/60

    The #4 solution

    We can use

    AWS Security Token Service to grant temporary credentia

    for non autheticaded users.

    They are called Federated Users.

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    19/60

    HTML/JS APP

    STS

    S3

    DB

    IAM

    LOGIN WITH

    ASSUME ROLE

    ACCESS TO SERVICES

    OK

    OKOK

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    20/60

    Create an app that helps users to store incomes/expenses and trac

    So we need:

    - a database service where store private cashflow entrie

    - a storage service where upload private files (receipts, invoice

    - a authentication service that manages the access to database a

    - an AngularJS app that merge al previous

    Example

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    21/60

    Simple Storage S

    DynamoDB

    IAM

    STS

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    22/60

    Step #1: set the storage serv

    Simple Storage Service (S3) is a

    Cloud storage that lets us to PUT and GET

    private (backup, private images)

    and public (js, css, public images) files.

    We just have to cre

    (folder) in S3 where w

    fil

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    23/60

    Step #2: set the database se

    DynamoDB is a fully managed NoSQL

    database stored in the cloud.

    We pay for the throughput setted.

    For example:10 reads / 5 writes per sec = free

    100 reads / 25 writes per sec = $31.58/month

    We just have to cre

    table where store

    incomes and

    We set a low thro

    the b

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    24/60

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    25/60

    We have to choose the indexes for the table.

    We set a primary key(string type) calledus erID that will be useful

    We set also a range key (numeric type) called t i m e s t a m p that let

    quickly the entries ordering by insert datetime.

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    26/60

    We want to manage the authentication with certified external w

    such as Amazon, Google and Facebook.

    Step #3: create federated ap

    Go to http://login.amazon.com websites and create a new a

    There is possible get the code for the login, as following

    http://login.amazon.com/http://login.amazon.com/
  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    27/60

    Creating an app we get an ID

    allowed source (the url of ou

    web application). HTTPS is r

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    28/60

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    29/60

    Go back to http://aws.amazon.com/console,

    and add a new role in the IAM area linked to our Amazon A

    Step #4: create the IAM ro

    http://aws.amazon.com/consolehttp://aws.amazon.com/console
  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    30/60

    {"Version": "2012-10-17",

    "Statement": [{

    "Effect": "Allow","Action": "sts:AssumeRoleWithWebIdentity","Principal": {"Federated": "www.amazon.com"

    },"Condition": {

    "StringEquals": {"www.amazon.com:app_id": "XXYYZZ"

    }}

    }]

    }

    IAM lets users from our Amazon Login app to assume role:

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    31/60

    We add policy to this role giving

    full access to S3 and DynamoDB

    thanks to the policy generator:

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    32/60

    {

    "Version": "2012-10-17",

    "Statement": [

    {

    "Sid": "Stmt1291088462000",

    "Effect": "Allow","Action": [

    "s3:*"],

    "Resource": [

    "arn:aws:s3:::financeapptest"]

    },

    {

    "Sid": "Stmt1291088490000",

    "Effect": "Allow","Action": [

    "dynamodb:*"],

    "Resource": [

    "arn:aws:dynamodb:eu-west-1:728936874546:table/finance "]

    }

    ]

    }

    This is an example of the policy generated (full access to S3 bucket and Dynamo

    G t d d dd ft

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    33/60

    window.onAmazonLoginReady = function() {amazon.Login.setClientId('YOUR-CLIENT-ID');

    };

    (function(d) {var a = d.createElement('script'); a.type = 'text/javascript';a.async = true; a.id = 'amazon-login-sdk';

    a.src = 'https://api-cdn.amazon.com/sdk/login1.js';

    d.getElementById('amazon-root').appendChild(a);

    })(document);

    Get your code and add after

    document.getElementById('LoginWithAmazon').onclick = function() {

    options = { scope : 'profile' };

    amazon.Login.authorize(options, 'https://www.example.com/handle_login.p

    return false;

    };

    Create a button (#LoginWithamazon) and the click event:

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    34/60

    new AWS.STS().assumeRoleWithWebIdentity({RoleArn: the-arn-of-the-role,

    RoleSessionName: the-name-of-the-role,WebIdentityToken: ACCESS_TOKEN,

    ProviderId: "www.amazon.com"}, function(err, data){

    if(data && data.Credentials) {console.log(data); //we get the Amazon User ID

    }});

    };

    User is redirected to https://www.example.com/handle_login.php?ACCESS_TOKE

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    35/60

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    36/60

    var dynamo = AWS.DynamoDB({region: dynamo.putItem({

    TableName: "finance",

    Item: data});

    Now we can PUT da

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    37/60

    var bucket = new AWS.S3({params: {Bucket: 'financeapptest'}});var fileChooser = document.getElementById('file-chooser');var file = fileChooser.files[0];

    if (file) {var params = {Key: file.name, ContentType: file.type, Body: bucket.putObject(params, function (err, data) {

    console.log(data);});

    }

    and uploa

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    38/60

    How to do that with:

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    39/60

    'use strict';

    angular.module('myApp', ['ngRoute',

    'myApp.filters','myApp.services','myApp.directives',

    'myApp.controllers']).

    .constant('configAWS', {tableName: "finance5",bucketName: "financeuploads",

    region: "eu-west-1"}).constant('configLogger', {

    amazonAppId:your-amazon.com-app-id',amazonRoleArn: 'arn:aws:iam::xxxxxx:role/amazon-login ',

    amazonRoleName: "amazon-login",});

    When you start the APP you have to set the Amazon.com app id and AWS role

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    40/60

    Thanks to that you have a configuration available along y

    Now we have to find a way to work with cloud services in

    the AWS SDK in our app. There are several ways to to th

    AngularJS. In this case we create factory services to wra

    needed feature.

    Firstly, a service to manage the auth.

    'use strict';

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    41/60

    angular.module('myApp.services', [])//provide methods to manage credentials of federated user

    .factory('loggerManager', function(configLogger, $location, $rootScvar baseFactory = {

    handler: new AWS.STS(),provider: false,

    credentials: {},id: false

    };

    /*** logout method (based on ID provider)

    */baseFactory.logout = function() {

    if(baseFacory.provider == "amazon") {amazon.Login.Logout();

    }};

    /*** login method (based on provider)

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    42/60

    * @param provider the name of provider* @param data data used for the login* @param redirect the destination after login*/baseFactory.login = function(provider, data, redirect) {

    //get the access params from AWS with the amazon loginif(provider == "amazon") {

    AWS.config.credentials = new AWS.WebIdentityCredentials({RoleArn: configLogger.amazonRoleArn,

    ProviderId: 'www.amazon.com', // this is null for GoogleWebIdentityToken: data.access_token

    });//assume role from AWSbaseFactory.handler.assumeRoleWithWebIdentity({

    RoleArn: configLogger.amazonRoleArn,RoleSessionName: configLogger.amazonRoleName,WebIdentityToken: data.access_token,ProviderId: "www.amazon.com"

    }, function(err, data){//login ok

    if(data && data.Credentials) {

    baseFactory.provider = provider;baseFactory.credentials = data.Credentials;baseFactory.id = data.SubjectFromWebIdentityToken;if(redirect) {

    $location.path(redirect);$rootScope.$apply();

    }}

    });

    }};

    /*** return the access key provided by amazon, google, fb.../

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    43/60

    */baseFactory.getAccessKeyId = function() {

    if(baseFactory.credentials.AccessKeyId) {return baseFactory.credentials.AccessKeyId;

    }else {

    return "";}

    };

    /*** return the id provided by amazon, google, fb...*/baseFactory.getSecretAccessKey = function() {

    if(baseFactory.credentials.SecretAccessKey ) {return baseFactory.credentials.SecretAccessKey;

    }else {

    return "";}

    };/**

    * return the user id*/baseFactory.getUserId = function() {

    if(baseFactory.id) {return baseFactory.id;

    }else {

    return "";}

    };return baseFactory;

    })

    Then, a service to work with S3. This is a tiny example:

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    44/60

    y p

    // provides methods to put and get file on S3.factory('s3Ng', function(configAWS, loggerManager){

    var baseFactory = {handler:false

    };/**

    * start the service*/baseFactory.build = function() {

    baseFactory.handler = new AWS.S3({params: {Bucket: configAW};

    /*** put file on the cloud storage* @param fileName* @param fileBody*/

    baseFactory.put = function(fileName, fileBody) {var params = {Key: loggerManager.provider + "/" + loggerMan

    + "/" + fileName, Body: fileBody};baseFactory.handler.putObject(params, function (err, data)

    console.log(data);});

    };return baseFactory;

    })

    Wotking with Dynamo is more complex. This is an exampl

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    45/60

    g y p p.factory('dynamoNg', function (configAWS, loggerManager) {

    var baseFactory = { handler:false };//build the servicbaseFactory.build = function() {

    baseFactory.handler = new AWS.DynamoDB({region: configAWS.region});};/*** put an element in to dynamo table. Data is a formatted json for dynamo

    * @param table name* @param data are the data in JSON formatted for DynamoDB* @return the result of the query*/baseFactory.put = function(table, data) {

    return baseFactory.handler.putItem({TableName: table,Item: data

    });};/*** Get an element from a DynamoDB table

    * @param table name* @param data the key to fetch* @return elements by the table*/baseFactory.get = function(table, data) {

    console.log("getting");return baseFactory.handler.getItem({

    TableName: table,Key: data

    });};

    /*** parse the dynamo data

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    46/60

    * @param the data* @returns the data extracted*/baseFactory.reverseModel = function(response) {

    var result = [];if(response.data.Count) {

    for(var ii in response.data.Items) {

    var item = response.data.Items[ii];result[ii] = {};for(var kk in item) {

    if(item[kk].S) {result[ii][kk] = item[kk].S;

    }if(item[kk].N) {

    result[ii][kk] = item[kk].N;}//binary type is missing!

    }}

    }return result;

    };return baseFactory;

    });

    // provides methods to put and get file on S3.factory('s3Ng', function(configAWS, loggerManager){

    b F t {

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    47/60

    var baseFactory = {handler:false

    };/*** start the service*/baseFactory.build = function() {

    baseFactory.handler = new AWS.S3({params: {Bucket: configA};

    /*** put file on the cloud storage* @param fileName* @param fileBody*/baseFactory.put = function(fileName, fileBody) {

    var params = {Key: loggerManager.provider + "/" + loggerMa+ "/" + fileName, Body: fileBody};

    baseFactory.handler.putObject(params, function (err, data) console.log(data);});

    };return baseFactory;

    })

    In a controller, start the auth:$

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    48/60

    .controller('HomeCtrl', function($scope) {

    // login button to auth with amazon.com appdocument.getElementById('LoginWithAmazon').onclick = function() {var options = { scope : 'profile' };amazon.Login.authorize(options, '/dynamofinance/app/#/logged/amazon');return false;

    };})

    And a controller to manage login (after app auth) and logo.controller('LoginCtrl', function($scope, $routeParams, loggerManager) {

    //user comes back from amazon.com app login successif($routeParams.access_token) {

    //do the login with the provider got by the urlloggerManager.login($routeParams.provider, $routeParams, "/finance

    };}).controller('LogoutCtrl', function($scope, $routeParams, loggerManager) {

    loggerManager.logout();})

    In a controller, how to work with services:t ll ("Fi Ct l" f ti ($ $ t P d N d Fi T bl

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    49/60

    .controller("FinanceCtrl", function($scope, $routeParams, dynamoNg, dynamoFinanceTablloggerManager, configLogger, configAWS){

    //build servicesdynamoNg.build();s3Ng.build();//.... More code here//upload file to S3$scope.uploadFile = function() {

    s3Ng.put("your filename", $scope.upload);$scope.entryId = false;

    };//store movement$scope.add = function(el) {

    //prepare the data to storeel.date = el.date.toString();var movement = dynamoFinanceTable.modelAmount(el);//store the data$scope.putMovement(movement);$scope.formReset(false);

    };$scope.putMovement = function(movement) {

    dynamoNg.put(configAWS.tableName, movement).on('success', function(response) {

    $scope.entryId = response.request.params.Item.date.S;$scope.$apply();

    }).on('error', function(error, response) { console.log(error); })

    .send();};

    //... More code here});

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    50/60

    You can find an example on GitHub: its a work-in-prog

    dont use in production. Its under dev and test

    https://github.com/gmittica/angularjs-aws-test-ap

    But our work is not finished.

    https://github.com/gmittica/angularjs-aws-test-apphttps://github.com/gmittica/angularjs-aws-test-apphttps://github.com/gmittica/angularjs-aws-test-app
  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    51/60

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    52/60

    The files & data that were storing in AWS

    are protected by unauthorized users,

    but are fully visible by other authorized users.

    Each user has access to data of the other ones.

    Security problem

    We have to refine the policies adding fine-grained conditio

    Step #5: fix the role policy

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    53/60

    Step #5: fix the role policyIn Simple Storage Service, we can limit the access of each

    specific subfoldercalled with his userId.

    {"Effect":"Allow","Action":[

    "s3:ListBucket"],

    "Resource":[

    "arn:aws:s3:::financeuploads"],

    "Condition":{

    "StringLike":{"s3:prefix":[

    "amazon/${www.amazon.com:user_id}/*"]

    }

    }

    },

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    54/60

    {

    "Effect":"Allow","Action":[

    "s3:GetObject","s3:PutObject","s3:DeleteObject"

    ],

    "Resource":[

    "arn:aws:s3:::financeuploads/amazon/${www.amazon.com:user_id}"arn:aws:s3:::financeuploads/amazon/${www.amazon.com:user_id}/

    ]

    },

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    55/60

    In DynamoDB, thanks to fine-grained access

    we can allow the access only to the rows

    owned by the user (the rows with hisuserID)

    It is also possible restrict the access

    role to specific columns.

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    56/60

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    57/60

    The data are now protected in the right way.

    Each user has access to his data.

    The app is now completed

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    58/60

    The app is now completed.

    Simple Storage Se

    DynamoDBIAM

    STS

    We can create other apps that works with

    the data thanks to different policies:

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    59/60

    The cloud is perfect for growing projects,

    thanks to the scalability of services

    and the cost saving

    especially in the startup stage.

  • 8/11/2019 Javascript Cloud Slideshare 140210053940 Phpapp02

    60/60

    Thank you!Any questions?

    @gabrielemittica

    [email protected]