How to use Firebase's email & password authentication method to connect with AWS to make Fine Uploader S3 work?
Asked Answered
G

2

8

I decided to use Fine Uploader for my current AngularJS project (which is connected to hosted on Firebase) because it has many core features that I will need in an uploader already built in but, I am having trouble understanding how to use Firebase's email & password authentication method to communicate with AWS (Amazon Web Services) to allow my users to use Fine Uploader S3 to upload content. Based on Fine Uploader blog post Uploads without any server code, the workflow goes like:

  1. Authenticate your users with the help of an identity provider, such as Google
  2. Use the temporary token from your ID provider to grab temporary access keys from AWS
  3. Pass the keys on to Fine Uploader S3
  4. Your users can now upload to your S3 bucket

The problem is that I won't be using OAuth 2.0 (which is used by Google, Facebook or Amazon to provide user identities) to allow my user's to sign into my app and upload content. Instead I will be using Firebase's email & password authentication.

So how can I make Firebase's email & password authentication method create a temporary token to grab temporary access keys from AWS and pass those keys on to Fine Uploader S3 to allow my users to upload content to S3?

Gautious answered 8/10, 2014 at 20:27 Comment(8)
did you make any progress on this? I have been researching this as wellBaer
I had to hold off for now since other parts of my app needed attention. Are you going to be pushing through to a solution in the next few weeks? Kato provided an answer that has some clues in it. This link firebase.com/docs/web/guide/user-auth.html and this link firebase.com/docs/web/guide/login/password.html contains valuable info.Gautious
I definitely have a solution to this, but it will require server code. AWS provides a way to generate OpenID tokens with an interaction between your backend and Cognito, but you do not want to expose that work client side. Only reason I hold back is you mention doing work w/o server code?Baer
I have heard this from other sources, that we will need server side code to generate a token for S3 authentication. Something along those lines. I was planning on using Express 4 for this. So if you have a solution please let me know as I'm in line with your approach.Gautious
Oh I found this guide on Cognito and Angular matthewgladney.com/blog/angular/… too bad Firebase does not support OpenID. Can't believe that.Gautious
Ha that's actually my blog :) I was planning on putting in the relevant steps later today when I had some time. Let me know if you have any snags - I was pulling together some excerpts from my project. I'll get the answer up later todayBaer
Oh excellent! I started going through it. I will let you know if I hit snags :) And also look forward to the answer. I'm sure others will benefit from it too.Gautious
I posted a consolidated version that's focused on the node interaction below about 1hr agoBaer
B
2

To connect AWS with an outside application, Cognito is going to be a good solution. It will let you generate an OpenID token using the AWS Node SDK and your secret keys in your backend, that you can then use with the AWS JavaScript SDK and WebIdentityCredentials in your client.

Note that I'm unfamiliar with your specific plugin/tool, but this much will at least get you the OpenID and in my work it does let me connect using WebIdentityCredentials, which I imagine is what they are using.

  1. Configure Cognito on AWS

Setup on Cognito is fairly easy - it is more or less a walkthrough. It does involve configuring IAM rules on AWS, though. How to set this up is pretty project specific, so I think I need to point you to the official resources. They recently made some nice updates, but I am admittedly not up to speed on all the changes.

Through the configuration, you will want to setup a 'developer authenticated identity', take note of the 'identity pool id', and the IAM role ARN setup by Cognito.

  1. Setup a Node Server that can handle incoming routes

There are a lot of materials out there on how to accomplish this, but you want to be sure to include and configure the AWS SDK. I also recommend using body-parser as it will make reading in your POST requests easier.

var app        = express();
var bodyParser = require('body-parser');
var AWS        = require('aws-sdk');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
  1. Create POST Function to talk with Cognito

Once you have your server setup, you then reach out to Cognito using getOpenIdTokenForDeveloperIdentity. In my setup, I use authenticated users because I expect them to come back and want to be able to continue the associations, so that is why I send in a UserID in req.body.UserIDFromAngularApp.

This is my function using express.router().

.post(function(req, res) {
   if(req.body.UserIDFromAngularApp) {
      var cognitoidentity = new AWS.CognitoIdentity();
      var params = {
         IdentityPoolId: 'your_cognito_identity_pool_id',
         Logins: {
            'your_developer_authenticated_identity_name': req.body.UserIDFromAngularApp
         }
      };
      cognitoidentity.getOpenIdTokenForDeveloperIdentity(params, function(err, data) {
         if (err) { console.log(err, err.stack); res.json({failure: 'Connection failure'}); }
         else {
            console.log(data); // so you can see your result server side
            res.json(data); // send it back
         }
      });
   }
   else { res.json({failure: 'Connection failure'}); }
});

If all goes well, that will return an OpenID Token back to you. You can then return that back to your Angular application.

  1. POST from Angular, Collect from Promise

At the very least you need to post to your new node server and then collect the OpenID token out of the promise. Using this pattern, that will be found in data.Token.

It sounds like from there you may just need to pass that token on to your plugin/tool.

In case you need to handle authentication further, I have included code to handle the WebIdentityCredentials.

angular.module('yourApp').factory('AWSmaker', ['$http', function($http) {
   return {
      reachCognito: function(authData) {
         $http.post('http://localhost:8888/simpleapi/aws', {
            'UserIDFromAngularApp': authData.uid,
         })
         .success(function(data, status, headers, config) {
            if(!data.failure) {
               var params = {
                  RoleArn: your_role_arn_setup_by_cognito,
                  WebIdentityToken: data.Token
               };
               AWS.config.credentials = new AWS.WebIdentityCredentials(params, function(err) {
                  console.log(err, err.stack);
               });
            }
         });
      }
}]);

This should get you on your way. Let me know if I can help further.

Baer answered 17/2, 2015 at 20:34 Comment(2)
Ok this is great. I realize I should first deal with successfully updating my outdated auth related AngularFire Firebase code. Once that is done I will revisit this but right off the bat after reading through this, I am trying to understand where Firebase auth comes into place here. Also I will have to deal with integrating Express into my current Angular app. So lots to do and lots of questions but if I need to I will ask new ones to stay organized. Thanks! :)Gautious
I'm implementing this for a Polymer app since we needed to handle video and live stream and Firebase wouldn't be an option. But for everything else we're using Firebase so I needed a way to keep track of my users accross Firebase and AWS. Thank a lotLament
Y
0

Each OAuth provider has a slightly unique way of handling things, and so the attributes available in your Firebase authenticated token vary slightly based on provider. For example, when utilizing Facebook, the Facebook auth token is stored at facebook.accessToken in the returned user object:

var ref = new Firebase(URL);
ref.authWithOAuthPopup("facebook", function(error, authData) {
  if (authData) {
    // the access token for Facebook
    console.log(authData.facebook.accessToken);
  }
}, {
  scope: "email" // the permissions requested
});

All of this is covered in the User Authentication section of the Web Guide.

Yvette answered 13/10, 2014 at 17:38 Comment(1)
Right but how can I make Firebase's email & password authentication method create a temporary token to grab temporary access keys from AWS? No where in Firebase docs does it explain how to do this.Gautious

© 2022 - 2024 — McMap. All rights reserved.