skip to Main Content

I am using the MERN stack for an app im building. In this app im using twilio. I have decided to use twilio sub-accounts. The way this works is I create a MASTER twilio account that give me an accountSid and authToken.

I can store these as ENV variables in Heroku when I want to deploy, and anytime I need to access these ENV vars I can just use the process.env.AUTH_TOKEN in my Node.js server.

Every customer that signs up for my app is going have their own subaccount that is a child of my MASTER account. When this sub account is created, It will give that user their own accountSid and authToken.

This is where my issue stands, Do I need to store each users authToken on Heroku as an ENV variable?

ex..

process.env.USER_1_AUTH_TOKEN
process.env.USER_2_AUTH_TOKEN
process.env.USER_3_AUTH_TOKEN
process.env.USER_4_AUTH_TOKEN
process.env.USER_5_AUTH_TOKEN

I dont think this will work because how will I know which users auth token belongs to them?

Currently in Development I am storing the sub-account authToken directly on the user object, this user object is visible to the client side of the app and im worried that exposing the auth token directly to the client could result in some sort of hack?

Is it safe to store the auth token on the user object directly in mongodb and whenever my react app needs the user, just send the user object without the auth token?

Should I create a auth-token Model, and store a document in the auth-token model containing the auth-token and user_id and everytime I need the auth token just query mongodb for the auth-token with user_id as a parameter?

How does one go about storing say 100,000 of these auth-tokens?

I’m worried about security and twilio docs dont say much about this…

2

Answers


  1. Chosen as BEST ANSWER

    I would like to add some additional info for anyone using twilio subaccounts.

    So what I did was create a master account with twilio. This gives you an accountSid and authToken.

    These you can store in Heroku under config vars.

    When you create your login function for a user via passport login, google-passport or some custom login you create, make your api call to create a subaccount. ( Like when you buy numbers, you buy them under your main account and drill them to your sub accounts) When this is created ONLY add the sub account accountSid to your user object. the sub accountSid is worthless without the auth-token and since you need to make an api call with your env vars your sub account auth tokens are safely stored in twilio.

    Now whenever you need to make twilio api calls, say for sending a message or making a phone call etc... first make a call to this endpoint

    client.api.v2010.accounts(subActServiceSid)
        .fetch()
        .then(account => account.authToken);
    
    
    const accountSid = keys.accountSid // master accountSid
    const authToken = keys.authToken // master authToken 
    // these will be stored in heroku
    
    
    const listChatMessages = async (req, res) => {
      
        const { subActServiceSid } = req.user // getting sub accountSid from user object
    
        const subActAuthToken = client.api.v2010.accounts(subActServiceSid)
        .fetch()
        .then(account => account.authToken);
    
    
        const subClient = require('twilio')(subActServiceSid, subActAuthToken)
    
     await subClient.messages.list({ // make all the api calls your heart desires
                from: chat.phone
            })
            .then( messages => messages.forEach((m) => { console.log("message", m})
    

    this will contain a JSON object with the sub accounts authToken. You can then use this authToken for the API call. No need to worry about storing 100,000 users authTokens somewhere.... If this is still confusing message me.


  2. According to the Subaccounts API documentation you can use the Twilio rest API to instantiate a subaccount and assign that subaccount a friendly name that is easy to retrieve.

    client.api.v2010.accounts
        .create({friendlyName: 'Submarine'})
        .then(account => console.log(account.sid));
    

    This returns an object that contains a lot of information but it has a unique SID for that is associated to that new number/subaccount. That object is then also linked back to your main account via the owner_account_sid which is attached to that object.

    Twilio provides functionality in the subaccount API to allow you to retrieve a subaccounts data based on the friendly name like so…

    client.api.v2010.accounts
        .list({friendlyName: 'MySubaccount', limit: 20})
        .then(accounts => accounts.forEach(a => console.log(a.sid)));
    

    So what you should be doing is as follows…

    1. Create a naming convention within your system that can be used to form friendly names to assign to subaccounts.
    2. Use the API to create a new subaccount with the Twilio API under the friendly naming convention you’ve developed.
    3. Anytime you want to make a call, text, or other supported action from the Twilio API first perform an API action to look up the SID of that account by the friendly name.
    4. Grab the sid the friendly name returns and attach it to your client object like so require('twilio')(accountSid, authToken, { accountSid: subaccountSid });
    5. Perform your action through that client using the subaccount Sid that is now attached.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search