I'm currently trying to create managed accounts entirely clientside, storing on the backend only the stripe account ID associated with each user. At first, I tried using stripe.js, but it doesn't seem to provide any API for working with managed accounts at all. Then, I tried using RESTful API directly, and made a request to create a managed account (a POST request to https://api.stripe.com/v1/accounts), using a publishable key. Response was a 403:
{
"error": {
"type": "invalid_request_error",
"message": "This API call cannot be made with a publishable API key. Please use a secret API key. You can find a list of your API keys at https://dashboard.stripe.com/account/apikeys."
}
}
But doesn't that mean that creating a managed account clientside is impossible or, at least, unsafe and not intended? Secret key is not supposed to become visible to the client at any point and in any form, is it? Is there something I don't understand, or are managed accounts to be created only serverside?
Stripe integrations require both a front-end and a back-end component.
You use Checkout or Stripe.js and your Publishable Key to collect a Customer's credit card information, which is then sent to Stripe. In return Stripe sends back a token that you can use to charge this card.
https://stripe.com/docs/checkout
https://stripe.com/docs/stripe.js
You must use a backend, with your Secret Key, to create an account, a charge, a customer or take other actions on your account. So, yes, managed accounts are only created server-side.
If you need a minimal backend I'd suggest spinning up a small instance at AWS, Heroku, Digital Ocean, Linode, etc
Related
I want to trigger my Cloud Function via HTTP but also authenticated with IAM and a service account auth0-hook I created therefore.
I generated a private key like this:
gcloud iam service-accounts keys create ~/.gcp-keys/auth0-hook-sa.key.json --iam-account=auth0-hooks#my-platform.iam.gserviceaccount.com
and applied this service-account to my cloud function.
On the outside - in the Auth0 Hook code - I know need to fetch the credentials first and send the fetched token with the POST request to the Cloud Function endpoint.
My problem here is that I can not use any of the Google Auth client libraries (Node.js in this case) because Auth0 Hooks can not import any fancy libraries as it seems.
I am hereby stuck with only using var request = require('request#2.56.0'); to make this all work.
I'd like to ask how I can manage this? There is some authentication service I can call right? But what is the API for that one? In the docs I could not find the manual way but only the client library documentations.
I am hereby stuck with only using var request =
require('request#2.56.0'); to make this all work. I'd like to ask how
I can manage this? There is some authentication service I can call
right?
Google does not provide a simple HTTP endpoint that you can call. If you think thru the process, you need the authorization to call an endpoint that generates authorization credentials. Chicken and Egg situation.
Google does not yet accept Auth0 credentials at an endpoint to exchange for Google credentials. However, keep reading for more information about Workload Identity Federation, which can/might provide that ability eventually.
There is no simple answer for your goal of creating an Auth0 hook that can generate a Google Access or Identity Token. Below are details to help understand what is possible.
To go from a Google Cloud service account JSON key file to an Access Token requires libraries also. The process is to create a JWT, sign the JWT, exchange the JWT for an access token. I wrote an article that shows how to do this in Python. The process for Node.js is similar. Your issue is that the process is too complicated for an Auth0 hook.
Google Cloud – Creating OAuth Access Tokens for REST API Calls
Google has recently introduced Google Workload Identity Federation which supports exchanging OIDC tokens for a Google OAuth access token via federation and service account impersonation. The process is just a series of HTTP method calls. I am authoring several articles on how to do this, but I am not finished at this time.
Accessing resources from an OIDC identity provider
One possibility is to create another Cloud Function or Cloud Run service that you can call in a single HTTP GET that creates the tokens for you. That way you can use Google Client libraries. Your Function/Run code would receive an HTTP GET request, interface with the client libraries to create the access token and return the token as the HTTP GET response.
However, that creates the Chicken and Egg situation. You need to authorize the request to the Function/Run code to get an access token.
You may want to change strategies and instead disable Cloud Functions authorization and verify the Auth0 Identity Token within your code and skip Google-based authorization.
Auth0: Validate ID Tokens
Auth0: Validate JSON Web Tokens
Pay attention to whatever process you choose as getting authorization correct and secure is not easy.
Note: Your question states "I want to trigger my Cloud Function via HTTP". I am not sure what method you plan to use. If you are using Cloud Functions Authorization, that requires an OAuth Identity Token. That adds more steps to the process. I have not figured out how to do that with Workload Identity Federation, but the Functions/Run code can easily handle that for you.
In summary, Cloud Functions are intended for small, light-weight code in a serverless framework. Once you add authorization, complexity grows. Provided you stick with Google Cloud authorization, everything is easy. Once you try to go from one identity system (Auth0) to another (Google Cloud IAM) the complexity jumps dramatically.
I have and app that uses connected accounts with Stripe. I need to store information about which Stripe account is linked to the specific client in my app. So my current workflow is:
I set a Stripe Account Id to the client of my app in Database
On the specific page, my Frontend sends request about which Account Id is linked to the specific client
I send a Stripe Account Id as a response to my Frontend
I process Card information with the connected account on my Frontend and send the Token to my Backend
On the backend, I create Source and retrieve it back to Frontend
On the Frontend, I handle the possible 3DS and send a Source back to my Backend
On the backend, I finish the payment and send status back to my Frontend
So, my question is - Is there any possible security risk during the process? I could not figure out any other way of passing Account Id information to the frontend. I need to initialize Stripe on Frontend with a specific Account Id to check Credit card data via Stripe Elements. Without the Account Id in my Frontend, I cannot create Card payment linked to the specific connected Stripe Account, so I think, there is no other way - Am I wrong?
As clients in my application changes, there is no possibility to store an Account Ids in an ENV file, I just have to get it from my server somehow.
I also tried to check Card info via Stripe elements using just PK stored in my ENV file, but then, when I wanted to finish payment with a connected Account, the process failed.
Do you guys have any secure workflow for this situation?
Sharing account and source (did you mean PaymentMethod?) IDs with your frontend is not just fine, it's expected. In order to make requests with Stripe.js on behalf of connected accounts you need to provide the account ID when initializing.
Doing anything malicious with those IDs requires a secret key, which as long as you aren't sharing that with the client you should be fine.
In my project I need to link an existing email account whithout the user signed in.
I have the user's email, so I'm trying this code:
firebase.auth().getUserByEmail(useremail);
on the client side.
But it gives me the firebase.auth(...).getUserByEmail is not a function error.
Does anyone know how to get the user by email address on the client side so I can link the accounts, the existing one and the providers?
Thanks in advance.
Using sdk 17.4.5
For web clients, firebase.auth() returns an Auth object. As you can see from the API documentation, there is no getUserByEmail method. on it. You're probably looking at the API documentation for Auth from the Firebase Admin SDK, which does not work on web clients. It only works on backends running nodejs.
If you want to use getUserByEmail, you'll need to run it on a backend, and invoke that from your web client.
You should know that linking user accounts does actually require the use of this method. You link accounts after the user has signed in to both of them.
I have a tiny table (100 records) that I keep in my Dynamodb backend. My web app will scan table at the beginning of the session. And then users will query this data with different parameters. My intention is not to go my backend for each query and do it on client side(front end) for better performance.
But because I don't want anyone to see my tiny table's data I would like to encrypt it while sending and decrypt it on browser side after arrival. I'm using Nodejs, dynamodb and API gateways as backend (AWS serverless architecture).
I'm a newbie and was wondering if it is possible and what the best practices are.
I'll give an example to describe my concern better. Imagine skyscanner keeps all airline-flight-ticketprice data in one table. they will have 2 options to let everbody to search publicly. First they can let users to query the table everytime they search (which will be slow). Second they can scan the table's data and send it to browser and users can search flights much faste on front end (with arrays etc..). I want to implement the 2nd approach but I also want to keep my data encrypted so nobody can copy my data and create a very similar website :)
Thanks.
Using Cognito Identity Pools
You can achieve this with authentication using AWS Cognito Identity Pool(Granting who can access which DynamoDB Table and even which Partition key) and using AWS JavaScript SDK which uses SSL to encrypt the communication between the browser and DynamoDB.
Note: You can also use AWS Cognito UserPools if you don't have a user store which can be connected to Cognito Identity Pool.
Using API Gateway and Lambda endpoint for Temporary Access Credentials
If you already have an existing authentication mechanism you can use a API Gateway and Lambda endpoint where the Lambda function will have the code to assume an IAM Role and send the temporary access credentials to the browser. Then in the browser you can use AWS SDK for JavaScript to access DynamoDB.
Here's a demo app that does specifically what you're looking for...once logged in, the user has access to his own "row" in dynamoDB...
https://github.com/awslabs/aws-cognito-angular-quickstart
Here's what you get by running the install script (it creates all of the resources for you):
http://cognito.budilov.com
I'm trying to use Trello API to create cards on our boards. But i cannot really bypass authentication programmatically, because a user prompt always appears asking for authentication in trello.
The idea is i create a system user on trello, add it to the boards, then use its API key to create the cards. I'm following this approach because I used Zapier to generate cards from Freshdesk, and wondering how Zapier bypass OAuth to do this.
You simply cannot bypass the authentication of the API, however what you can do is to generate the valid oAuth tokens for your "System User" and use them for authentication.
I'm not aware of the complete Auth process of trello, but most oAuth providers give you the possiblity to create tokens which last quite long (refresh tokens). You could use these in your code to call the api without any additional auth process.
You could also store the normal auth tokens and re-validate them from time to time using the prompt.
Best solution depends on what you are trying to achieve...