Trello OAuth only working with one Google Apps Script - api

Background
I am able to create Trello cards from Google Apps Script via the
Trello API using the OAuth 1.0 library. The principle is proven/code
works.
I have two distinct Google Apps Scripts projects that need to be able to create Trello cards.
The code in the two different Apps Scripts/Projects is identical - including the same API key/secret.
Only one Apps Script will create a Trello card. This is my problem.
If I reauthorise the other Apps Script, that script will work and the other will give me an API return of "invalid token" and vise-versa. Only one works at a time, but I need both to work.
My thoughts
I think that Trello, via OAuth, see each Apps Script is its own distinct project.
I think that because of this it won't let both apps use the same API key/secret to work with my Trello account. Only one project appears to be able to use the key/secret.
If this is the case I don't know how to make each Apps Script its own project for the Trello API to work for both simultaneously.
Help needed
Does anyone know how to make this work? I need both scripts to be able to create Trello cards. I have a feeling that each apps needs to identify itself uniquely, but I honestly have no idea.

This is really an OAuth logic issue, it's a feature, not a bug. In OAuth, your application exchanges refresh tokens for access tokens. The access tokens only have a limited life span.
When you use a refresh token to generate a new access token, you also get a new unique refresh token and your script stores this for future use, the old refresh token is no longer valid. Similarly, when you re-authorize the application, you get fresh tokens, and any previously generated tokens are rendered invalid.
So when you authorise one script using the same Client ID and Client secret as the other script, you get a new access token and refresh token, and the old credentials, stored by the other script, become invalid.
As a result, the other script can no longer exchange the refresh token it has stored for new access tokens, and it no longer works. Once you re-authorize this copy, the refresh token and access token in the other copy are invalidated in the same way. So you end up going in circles.
You have two options:
Set up a separate OAuth Client (with different Client ID and Client Secret) for each script.
Modify your scripts to use the same storage location for the OAuth Access Token and Secret.
The first approach is going to give you the most reliable consistent results. If you try the second approach, you could still have cases where the scripts run at the exact same time, and one has valid tokens while the other tries to use the now invalid ones. (race conditions).

Related

How to store and use multiple users' keys for third party client

I want to build web app that uses Spotify API. I got case where user has to authenticate with his spotify account, then I recive access and refresh token that is being used in code to authenticate calls to Spotify to perform some actions on user's account.
I have trouble deciding how it should be really done. First thing that came to my mind - store them in Redis for some time, update on refresh and whenever we need to perform some action on any user we get his credentials and do it. Is this proper way? I tough about simply storing them in app memory but I might want to make in serverless.
Did anyone come accross that kind of problem? Do anyone know how to do it 'properly'.

Auth0: Specific questions about token storage and flow for mobile app

I’m building a react native app that will interact with APIs that I also write/manage. I have found Auth0 documentation for implementing this flow, but I’m not sure on where/when to save the tokens. I want to be sure I nail this step, because I feel like it has the potential to reduce the security of the flow by a great deal if I don’t do it correctly.
Here is the flow as I understand it (no error handling, only happy-path for sake of brevity):
A user enters the app for the first time, or is not already logged in
They log in using the Auth0 web-login-thingy
I receive a token
I can use the token to authenticate with my API
Questions:
Do I store that token? I don’t want my users to have to log in every time they use the app. If I do store the token, where do I store it?
If I’m not storing it, what do I do? Do I ping an authentication/authorization endpoint with Auth0 every time they open the app and get a new token?
Say I am storing the tokens, if I'm using the ID token for user data, should I be hitting the API again regularly to keep it up to date? Only when the user opens the app again? Not until they trigger a change in the app?
Instead of using the ID token for user data, should I just use that to get the user's ID and ping my database for user data?
I have the basics of this flow, and I'm able to sandbox it, but I want to start applying production-ready app logic to this flow and that's where I'm stuck. I’m a little lost here, so any help is good help.
Thanks!!
Here's a brief answer to your questions when using Auth0:
Yes! you store it, the most secure way to store the token is in your device's local storage, that way it is not kept either in application's state or in a global variable.
2&3. See above, but to add more information, you can configure your tokens to have an expiry length. in theory you would convert this 'expiry time from inception' to a date object, and can do one of two things; you can request a new token using the Refresh Token (that comes with the original) once the expiry has been reached, or force the user to re-log in and re issue a new token at this time (i prefer the latter, prevents people from just renewing their tokens forever as long as they remain logged in)
Use the auth token to request user information after login, this can be stored in app state/global variables/wherever. You then want to use the auth token in the Authorization Header for each API call, along with whatever data you are sending. this ensures that even once someone is INSIDE the application, they need to have a valid token to actually do anything involving data (imagine someone back-dooring into your app and skipping the authorization, or using something like postman to just hammer your API with garbage). it would work something like this: GET userData { Header: auth token } -> GET userProfile (by sending your user ID returned from GET userData) PLUS {Header: auth token }
I can give more in depth examples if you wish, and i apologize if i misunderstood any of the question and gave redundant/incorrect answers
Edit: Resources about using secure storage for keys
Document for when to use in-memory storage Vs persistent storage. The TL;DR is use in-memory if the key is expected to expire before a standard session duration, and persistent for storing a key between sessions
https://hackernoon.com/mobile-api-security-techniques-682a5da4fe10
link to Keychain Services doc
https://developer.apple.com/documentation/security/keychain_services#//apple_ref/doc/uid/TP30000897-CH203-TP1
link to SharedPreferences doc
https://developer.android.com/reference/android/content/SharedPreferences.html
AsyncStorage is a simple, unencrypted, asynchronous, persistent,
key-value storage system that is global to the app. [1]
You could store it in your AsyncStorage, but thats not necessarily a secure location itself (e.g. not encrypted, accessible on rooted devices...). Typically clients will issue access tokens that last anywhere from several hours to a couple days and these will provide their owner access to your API-resources. If there is sensitive data behind your login screen, you're probably better off simply re-doing the auth-flow and invalidate older access tokens on login.

Architecture Design - REST API to support Facebook Login done by Mobile app

I am trying to design REST APIs to support various mobile clients (iOS and Android apps). These apps will let user login using facebook login along with our own email authentication. You can refer to the diagram below to understand my design
There are two levels of authorization take place:
First one is "Client (or App) Authorization" that uses OAuth2. So when user install our app on mobile device, and starts app, then very first thing, app makes "Client (App) Authorization" as shown in above diagram (1st image). And server sends back an long-lived access_token to client to use for all subsequent calls. Here my question are:
Q1) You can see client is sending client_key and client_secret and I am storing them in client_info table. Should this secret be in plain text or it should be in decryt-able format? If I encrypt it, I still need to keep encryption key somewhere in my system. So how it will make it secure? Also in every call, decryption will be an overhead.
Q2) Is it ok to cache access_token for the client in plain text format in redis and use that cache first?
Q3) In order to be extra safe, I am asking clients to send appsecret_proof to make sure the access_token, they are sending belongs to this client only. It uses the same concept as Facebook https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof. And it is hash_hmac('sha256', access_token, client_secret)
Q4) We will only have our own 2 mobile app (each for iOS and Android) and not providing third party to use our API to develop other apps. That means, our client_info table will only have two rows one for each type of apps. So is it okay, that in app code, we keep client_key and client_secret hardcoded? If yes, then in future when we have to invalidate and use new secret then how will we achieve replacing those info?
Q5) Since it is our own apps for couple of years, so there would be multiple access_token will get created against same client_key and client_secret. In order to save all of them, is it a good idea to store client_key as key and an array of all access_tokens as value in redis. In future, when we will open our API to third party, then this redis storage design can still scale?
=================
Later on, user decides to perform some actions on my app, for that we need user to login to his account. For that user click on "facebook login". My app gets facebook access_token and fb user's id from facebook and pass those info to API server (as shown in 2nd diagram). API server takes that token and call facebook API to validate its access_token. Once token is validated, server uses some metadata related to that user along with FB access token to generate our own user_access_token, lets say utoken. And pass that utoken back to client to pass back in every subsequent user specific API calls. Here my questions are:
Q1) Is it ok to save that utoken in database, user_token table. Should this utoken be in plain text or it should be in decryt-able format? If I encrypt it, I still need to keep encryption key somewhere in my system. So how it will make it secure? Also in every call, decryption will be an overhead.
Q2) In every user specific API calls, should I call facebook every time to check facebook access_token is still valid? I believe I should not, as that is not going to get anything to me. Please note, Facebook is ONLY used for "facebook login".
Q3) What are the information I should encrypt to generate utoken? I am thinking to have a hash or associative array of user's email, user id, role and facebook token and then serialize that data structure and finally encrypt it. Do you think that would be good enough. I understand its per my requirement, but as a standard or common app, are they good enough? Or is there any best practice?
Q4) Should client store utoken in its cookie/cache? Isn't that scary?
Q5) Please note user may have multiple devices, logged in with same user credential. That means, in user_token table, we would have to store multiple utokens for those logged-in session, while all of them will belong to the same user. Does that sound right?
A design proposal somewhat smiliar to mine REST API for website which uses Facebook for authentication
Q1.1: No!. Client credentials is not intended to be used that way. If your client is a Single Page App or a Mobile App, you will be forced to store your client credentials in an insecure environment, the user's machine. You should be using OAuth's Implicit flow
Q1.2: Assuming the token is short lived, no problem caching it. The key of OAuth, apart from ensuring that you can rely on other application to authenticate your users, is that you effectively substitute user or application credentials, which are long lived, with a short lived token. So if someone gains access to the token,at least, their access to the system will be limited in time.
Q1.3: Check out that facebook documentation:
Graph API calls can be made from clients or from your server on behalf of clients. Calls from a server can be better secured by adding a parameter called appsecret_proof.
It states that appsecret_proof is to be used for calls from the server on behalf of the user. The point here has to do with Q1.1. If you were storing your client_secret in your user's device, they could generate the appsecret_proof.
Q1.4: Again, No! You should have a good read of OAuth Specification and understand the different flow types and when to use each. Also bear in mind, that if you provide an API for your App the API is public for any one to abuse. The only difference is that it is not documented. The same will happen with a Web App. Once it is in the internet, I could write a scraper and abuse the Web App. This is perfectly normal, just bear in mind that anything on the internet is not private, it is just undocumented.
Q1.5: Again, tokens should be short lived. If their lifespan is the same of the credentials, which live until the user change them, then tokens lose their purpose.
Q2.1: You should save that token A ReST architecture uses a client cache constraint.
Q2.2: I don't think so. Facebook is just telling you that the user that obtained that token has some identity (an email, for example) that you can associate to a user in your system. Once you know that association you should't care much about the Facebook token but to make calls to Facebook API. But as you say, you are using it just for login.
Q2.3: Seems not bad but check again the Oauth Specification as you seem to be building an Implicit flow and using JWT tokens. As per what you want to store in your token, seems fine.
Q2.4: JWT tokens must be cached by the client. Nothing scary, because they are opaque to the client as they are encrypted. The client sends the JWT token with each request and the API server decrypts the token with a private key (that has never been exposed outside the server) and can check the identity of the user.
Q2.5: Remember short lived tokens. Tokens must expire!.

flickr api authentication without user intervention

I would like to programmatically query the Flickr API using my own credentials only just to grab some data from there on a frequent basis. It appears that the Flickr API is favouring OAuth now.
My question is: how should I authenticate the API without user intervention just for myself? Is it possible any more?
Once you have received an oauth_token (Access Token), you can use it for multiple subsequent API calls. You should be able to persist the token in a data store (I haven't done this myself) and use it even after your application restarts. Of course, you still need to write the code to get the Access Token the first time.
If your application is already coded using the old authentication API, it looks like there is a one-time call that you can make to get a new-style Access Token. See http://www.flickr.com/services/api/auth.oauth.html#transition
Even if you don't have a coded application, you might be able to use the API Explorer for any of the calls that requires authentication (flickr.activity.userComments, for example) to harvest an api_sig and auth_token.
The scenario which you are describing is sometimes referred to as 2-legged OAuth. (https://developers.google.com/identity/protocols/OAuth2ServiceAccount)
Google APIs support this via a 'service account'.
Unfortunately Flickr doesn't seem to support this kind of interaction.
For public data interaction (like downloading your public photos (photostream) from your account), there's no need to authenticate. You can get the data using only the Flickr user-id.
For other interactions (like downloading private photos (camera roll) from your account), you'll need to follow the full OAuth procedure at least once.

How safe am I signing into Google Spreadsheets with yeroon.net/ggplot2

I am impressed by what I have seen of yeroon.net/ggplot2 which is a web interface for Hadley Wickham's R package ggplot2. I want to try it out on my own data. The part that has me very excited is that one can use data stored in one's own Google spreadsheet as the data. One just signs into their Google Account so that yeroon.net/ggplot2 can access the spreadsheet list. I have been hesitant to do it. If I sign in whilst on yeroon.net am I handing over my username and password to a third party? It would not be wise of me to divulge my google password to third parties since Google is fast becoming my repository of everything.
How do I know if Jeroon's application is using ClientLogin or OAuth? My understanding is very basic and may be wrong but nevertheless here it is. OAuth would be better since it does not actually pass the password onto the third party application.
I am the creator of the yeroon.net/ggplot2, someone pointed me to this topic. I'll try to explain how the system currently works.
The application is using AuthSub authentication. The moment you sign into your Google account, a Google session is created. This session only has access to the Google documents and Google spreadsheet services that you gave permission for on the Google login page, so not to e.g. your mailbox.
Once you logged in, you retrieve a session token from Google: a unique key that belongs to the session and can be used to make requests to access your Google data. The session token is stored as a cookie on your browser until you close it. Every time you make a request to yeroon.net servers, this token is added to the request.
Using this token, the yeroon.net servers can access your google data, e.g. to retreive a spreadsheet. The token is not stored on the server, although I understand that you have to take my word on this. Also it is not possible to find out your username or password from the session token; it can only be used to retreive data, as long as the session lives.