javascript cloud slideshare 140210053940 phpapp02
TRANSCRIPT
-
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