PC & Mobile

Utilisation d'AWS lambda pour générer des URL prédéfinies – Andrew Trigg – Medium

Utilisation d'AWS lambda pour générer des URL prédéfinies - Andrew Trigg - Medium


Si vous souhaitez créer une application à une seule page avec la possibilité de télécharger des fichiers vers S3 sans révéler les variables d'environnement sensibles, vous pouvez le faire en utilisant une fonction lambda pour générer une URL prédéfinie. Cette URL générée peut être renvoyée à votre SPA, ce qui lui donne la possibilité (dans certaines restrictions, telles que la limite de temps et de fichiers) de télécharger directement à partir du client. Ceci est utile pour une raison autre que la sécurité; le client fait tout le travail pour télécharger le fichier.

Dans cette procédure pas à pas, nous allons configurer une application avec AWS appsync et l'amplifier, puis utiliser Vue.js pour notre client SPA.

Assurez-vous donc d’avoir vue-cli installé (j’utilise la version 3.1.3) et d’amplify-cli (j’utilise la version 0.2.1-multienv.22).

Commencez un nouveau projet de vue en tapant ce qui suit et en sélectionnant votre préréglage:

vue créer presigned-url-lambda

Déplacez-vous dans ce dossier nouvellement créé et initialisez-le en tant que projet amplifié

> cd presigned-url-lambda
> amplifier init

Répondez aux questions à l'invite selon vos besoins et une fois le processus d'initialisation terminé, ajoutez une API avec la commande suivante:

amplifier ajouter api

À l'invite, sélectionnez l'option graphql pour l'API, puis toutes les réponses par défaut aux autres questions (vous devrez peut-être modifier le nom de l'API si l'option utilise par défaut des caractères non autorisés).

Une fois que vous avez répondu «oui» à la modification du schéma, votre éditeur de texte s’ouvrira avec le schema.graphql fichier. Changez-le pour ressembler à ceci:

tapez Modform @model {
J'ai fait!
des dossiers: [String]
site: String
page: String
changements: String
}

tapez File @model {
nom: chaîne
URL: chaîne
type de fichier: chaîne
}

Une fois le schéma enregistré, retournez à la fenêtre de la console et appuyez sur Entrée pour continuer.

Ensuite, nous devons ajouter notre fonction lambda. Dans le type de console:

amplifie la fonction add

Une fois encore, vous serez invité à fournir des détails. Nous allons simplement utiliser les valeurs par défaut et répondre "oui" pour éditer la fonction lambda locale.

Un index.js Le fichier s'ouvrira, que vous devriez éditer pour ressembler à ceci:

const AWS = require ('aws-sdk');
// si vous utilisez une région de l'ue, vous devrez définir la signature
// version to v4 en passant cela dans le constructeur S3 -
// {signatureVersion: 'v4'}
const s3 = new AWS.S3 ();

exports.handler = fonction (événement, contexte) {

const bucket = process.env['s3_bucket']

si (! seau) {
console.log ('compartiment non défini:')
context.done (nouvelle erreur (`s3 bucket not set`))
}

clé const = `mon-emplacement / $ {event.input.name}`

si (! clé) {
console.log ('clé manquante:')
context.done (nouvelle erreur ("clé d'objet S3 manquante"))
revenir;
}

const params = {
«Seau»: seau,
«Clé»: clé,
ContentType: event.input.filetype
};

s3.getSignedUrl ('putObject', paramètres, (erreur, url) => {
si (erreur) {
console.log ('erreur:', erreur)
context.done (erreur)
} autre {
context.done (null, {
url: url,
nom: clé,
filetype: event.input.filetype
});
}
})

}

Enregistrez cela, revenez à votre console locale et appuyez sur Entrée.

Cette fonction prend essentiellement des informations d’une requête (le type mime du fichier et le nom du fichier. Elle crée une clé avec le nom du fichier (essentiellement le chemin du fichier dans S3) et utiliseS3.getSignedUrl () méthode pour obtenir une URL prédéfinie. Cette URL est renvoyée par la fonction.

Maintenant que nous avons configuré nos fonctions API et Lambda sur notre machine locale, nous devons transmettre ces détails à AWS:

amplifier la poussée

Cela va mettre en place toutes les ressources que nous avons définies, dans le cloud. Avant que le processus ne commence, un tableau dans la console nous indiquera les opérations en attente. Nous devrions avoir une opération ‘Créer’ en attente pour l’API et la fonction. Répondez «oui» pour continuer, puis fournissez la réponse par défaut aux prochaines questions pour générer le code pour notre API.

Une fois ce processus terminé, votre point d'extrémité GraphQL et votre clé API seront affichés. Vous devrez les mettre dans notre src / main.js fichier.

Mais avant cela, nous devons installer quelques paquets supplémentaires:

npm install --save graphql-tag@2.10.0 vue-apollo@3.0.0-beta.27 aws-appsync@1.7.0 axios@0.18.0

Ouvrez le src / main.js fichier dans notre projet et remplacez-le par le code suivant, en plaçant votre clé API et votre noeud final GraphQL à l'endroit indiqué:

importer Vue de 'vue'
importer l'application depuis './App.vue'

// vue-apollo facilite l’interaction de votre application vue avec le
// apollo-client dans le paquet aws-appsync, qui, à son tour,
// coordonne les échanges de données entre le magasin frontal et
// le backend store et s'occupe de la mise en cache, etc.
importer VueApollo de 'vue-apollo'
importer AWSAppSyncClient à partir de 'aws-appsync'

const config = {
URL: ,
région: 'us-east-1',
auth: {
type: 'API_KEY',
clé API:
}
}

// Le fetchPolicy par défaut est cache-first. Cela signifie que si les données
// est renvoyé du cache, aucune requête réseau ne sera envoyée. Si
// un nouvel élément est dans une liste, cela ne sera pas réalisé. Alors là nous
// change la politique pour que les requêtes réseau soient toujours envoyées après // les données renvoyées par le cache.
const options = {
defaultOptions: {
watchQuery: {
fetchPolicy: 'cache-and-network'
}
}
}
client const = new AWSAppSyncClient (config, options)
const appsyncProvider = new VueApollo ({
defaultClient: client
})
Vue.use (VueApollo)
Vue.config.productionTip = false
nouveau Vue ({
rendre: h => h (App),
apolloProvider: appsyncProvider
}). $ mount ('# app')

Et puis changez le src / App.vue fichier qui ressemble à ceci:

Créez la page de démonstration suivante à l'adresse src / components / DemoPage.vue:

const BASE_URL = 'https://presigned-demo-images.s3.amazonaws.com'

export default {
name: 'DemoPage',
data () {
return {
uploading: false,
images: [],
model: {
files: []
}
}
},
methods: {
addFilenameToModel ({target}) {
console.log('Loading...')
this.uploading = true

this.$apollo.mutate({
mutation: gql(createFile),
variables: {
input: {
name: target.files[0].name,
filetype: target.files[0].type,
// idOfSomeForm: like user id
}
}
})
.then(async ({data}) => {

try {

await axios.put(data.createFile.url, target.files[0], {
headers: { 'Content-Type': target.files[0].type }
})

console.log('Loaded')
this.uploading = false

this.images.push(`${BASE_URL}/${data.createFile.name}`)
this.model.files.push(`${BASE_URL}/${data.createFile.name}`)

} catch (e) {

// do we need to remove anything from the model here?
console.log('Upload failed!', e)

}
})
},
handleSubmit () {
this.$apollo.mutate({
mutation: gql(createModform),
variables: { input: this.model }
})
.then(a => {
console.log('Form stored in database')
})
},
}
}

.form entrée {
taille de police: 1em;
padding-left: 3px;
marge inférieure: 10px;
}

.btn-submit {
couleur de fond: # 7979de;
border-radius: 5px;
Couleur blanche;
marge supérieure: 10 px;
}

.btn-submit: désactivé {
opacité: 0,5;
}

.récipient {
affichage: flex;
justifier-contenu: espace-autour;
}

.image-container {
affichage: flex;
marge: 5px;
justifier-contenu: centre;
}

img {
hauteur maximale: 60px;
largeur maximale: 100px;
marge: 3px;
bordure: gris uni 1px;
}

Le front-end est maintenant configuré et vous devriez pouvoir exécuter l'application avec npm run serve. Lorsque vous le faites, vous verrez un formulaire avec des champs de saisie. Ouvrez vos outils de développement et essayez d’ajouter un fichier en utilisant l’entrée de fichier.

Vous serez accueilli avec une erreur: TypeError: impossible de lire la propriété 'protocole' de null

En effet, pour le moment, notre résolveur appsync graphql api n’est pas configuré correctement pour notre cas d’utilisation. Vous devez accéder à la section AWS Appsync de votre console aws, avec l’onglet ‘Data Sources’ actif. Cliquez sur le bouton ‘Créer une source de données’.

Remplissez les zones de saisie de manière appropriée, mais assurez-vous de définir le type de source de données sur "Fonction AWS Lambda" et de pointer sur la fonction que nous avons créée avec amplify. Le nouveau rôle donnera automatiquement la bonne permission.

Ensuite, toujours dans la section AWS Appsync, accédez à l’onglet Schéma, recherchez votre mutation ‘createFile ()’ dans la fenêtre ‘Resolvers’ et cliquez sur le résolveur auquel elle est actuellement associée. Au lieu de transmettre les données à DynamoDB, nous souhaitons qu'elles soient dirigées vers notre fonction Lambda, qui nous demandera une URL prédéfinie et la renverra.

Sélectionnez la source de données que nous venons de configurer et définissez vos modèles de mappage pour qu'ils transmettent les arguments et renvoient le résultat. Assurez-vous que vous appuyez sur Enregistrer!

Nous devons en fait créer un compartiment. Par conséquent, accédez à la section S3 de votre console AWS et cliquez sur le bouton "Créer un compartiment".

Renseignez les champs de saisie Nom du compartiment et Région. Assurez-vous que la région est compatible avec votre fonction lambda. Cliquez sur suivant et passez aux étapes suivantes sans apporter de modification jusqu’à ce que vous atteigniez le bouton "Créer un godet". Cliquez dessus.

Maintenant, si nous relançons notre application et essayons d’ajouter un fichier, nous obtiendrons l’erreur suivante: Erreur GraphQL: compartiment S3 non défini

En effet, dans la fonction que nous avons configurée, nous avons référencé une variable d’environnement qui n’existe pas encore. Voyons donc la section Lambda de notre console AWS, sous l’onglet ‘Fonctions’. La fonction que j'ai créée est mise en surbrillance, le vôtre aura un nom différent. Cliquez dessus et faites défiler jusqu’au volet ‘Variables d’environnement’. Nous voulons définir ceci pour qu'il pointe vers notre stockage S3.

Maintenant, lorsque vous essayez d'exécuter l'application et de joindre un fichier, vous obtenez une erreur 403 (interdite) et une erreur CORS. Nous devons ajuster les autorisations de notre s3.

Accédez à la section S3 de la console AWS et cliquez sur le compartiment que nous venons de créer. Cliquez ensuite sur l’onglet autorisations et sur le bouton 'Configuration CORS'. Vous pouvez trouver des exemples de stratégies CORS en cliquant sur le lien de la documentation. Nous allons utiliser la politique suivante:

Nous avions essentiellement besoin d'autoriser les méthodes http PUT et GET, ainsi que notre origine (probablement localhost: 8080 lors du démarrage de votre application vue avec npm run serve). Pour que vous puissiez couper, modifier et coller, le voici à nouveau:




http: // localhost: 8080
METTRE
OBTENIR
3000
*

Cela résoudra l’erreur CORS que nous avons rencontrée. Ensuite, nous devons accéder aux "Paramètres d’accès public" et éditer les stratégies de compartiment public comme indiqué dans l’image.

Cela nous permettra de créer une nouvelle politique.

Cliquez sur le bouton de politique de compartiment.

Vous pouvez utiliser le générateur de stratégies pour créer une stratégie adaptée à vos besoins. Nous devons autoriser les actions GetObject et PutObject et, comme nous voulons que l'application cliente (et toute personne l'utilisant) exécute ces opérations, nous avons défini le principal sur un caractère générique.

{
"Id": "Policy1547200240036",
"Version": "2012-10-17",
"Déclaration":[[
{
"Sid": "Stmt1547200205482",
"Action":[[
"s3: GetObject",
"s3: PutObject"
],
"Effet": "Autoriser",
"Ressource": "arn: aws: s3 ::: presigned-demo-2 / *",
"Principal": "*"
}
]
}

Si vous ne parvenez pas à enregistrer la stratégie et que l'erreur "Action ne s'applique à aucune ressource dans une instruction" s'affiche, ajoutez un caractère générique à la fin du nom de la ressource, car vous devez appliquer cette application. cette politique à toutes les ressources du compartiment. Assurez-vous de cliquer sur le bouton Enregistrer.

Vous devriez maintenant pouvoir exécuter l'application, ajouter des images au formulaire et enregistrer le formulaire avec un tableau d'URL pour les images. Hourra!

* Si vous trouvez que vous pouvez PUT les fichiers dans S3, mais vous ne pouvez pas les obtenir, assurez-vous que le BASE_URL dans votre DemoPage est configuré correctement pour pointer vers la source S3 correcte.

Show More

SupportIvy

SupportIvy.com : Un lieu pour partager le savoir et mieux comprendre le monde. Meilleure plate-forme de support gratuit pour vous, Documentation &Tutoriels par les experts.

Related Articles

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Close
Close