We are building a customer application. For that, we are using accounting software (ZOHO). Items will be fetched from the accounting software and bills will be generated directly on accounting software using API. API is using JWT for authentication. To generate JWT tokens for each user then is a 'user consent page', which should be manually approved from the web browser. So, for each customer we are not going to register as a user, we are planning to create them as just customers.
What we are actually planning to do now, is create one JWT token pair (After manual approval) and use it for all customers for all API calls. My first concern, is that will be a good approach?
The second concern, the Token has an expiry of 1 hour. After that, we should use the refresh token to generate the new token. How we can efficiently handle this on the web and mobile (Customers on the web and mobile simultaneously using the same tokens for API calls and the Token change should reflect on all client devices)? Doing this is a good idea?
In this case, you can create a Connection for Server-Based Application in Zoho Books and thereby authenticate the API calls using OAuth. When you set this integration up, the communication through API will be only between Zoho Books and your third-party application, and not directly between Zoho Books and your customers. Therefore, you can validate the user interface for your customers at your end.
When you initially build the API integration, you will be creating a Refresh Token. This can be hardcoded in your script and set to generate Access Token from it every hour. Please note that the Refresh Token and Access Token have to be generated separately for Web-based and Mobile-based applications. Here is our help resource for your reference. You can store the access token and expiry time, and verify the expiry time before using the access token. If it has expired, generate a new access token. Please take extra care to ensure that the refresh tokens are not exposed.
I hope this helps. Feel free to contact us if you have further queries.
Related
I am trying to build an python application for my server to run 24 hours and overwrite a file in dropbox every minute. When I built this application it stopped working after an hours for new token. I can't awake 24 hour to add new token every token. I just want a way that help me in doing setup of this. With dropbox there is no option to remove short length expire from token. Please keep it simple to underatnd easily dropbox documentation is hard for me to understand.
I just want a solution for this problem. I tried refresh token but it also required user interaction so no use.
Using refresh tokens is the right solution here. Just like with Dropbox access tokens, manual user interaction is required initially to get a Dropbox refresh token, but once the app has a refresh token it can store and re-use it repeatedly without further manual user interaction.
For reference, Dropbox is in the process of switching to only issuing short-lived access tokens (and optional refresh tokens) instead of long-lived access tokens. You can find more information on this migration here.
Apps can still get long-term access by requesting "offline" access though, in which case the app receives a "refresh token" that can be used to retrieve new short-lived access tokens as needed, without further manual user intervention. You can find more information in the OAuth Guide and authorization documentation.
You can find examples of using the OAuth app authorization flow in the Dropbox Python SDK here.
After reading around it appears that trying to protect a publically accessible API (API used by an app/site that does not need a user to log in) appears to be fruitless, e.g. store key in app, user can reverse engineer app.
My question relates to how one can protect as much as possible and slow down abuse of a public accessible API...
Rate-limiting? Check request origin (although can be spoofed).... anything else?
Also if the site is SSR, could it just be protected by the server's IP?
YOUR QUESTIONS?
After reading around it appears that trying to protect a publically accessible API (API used by an app/site that does not need a user to log in) appears to be fruitless, e.g. store key in app, user can reverse engineer app.
Security is all about defense in depth, thus is all about adding as many layers as you can afford and required by law in order to mitigate the risk, therefore any defense you add it's one more layer that will prevent that simple/dumb automated scripts from accessing it, while at same time will increase the level of skills and effort necessary for an hacker poking around to overcome all defenses.
Rate-limiting?
This is kind of mandatory for any API to employ, otherwise an automated script can easily extract an huge amount of data in seconds. The more strict this rate limit is applied, the greater may be the chances for other layers of defense to detect that unauthorized access to the API may be happening and try to mitigate/block it. To bear in mind that the rate limits can be bypassed by adapting the attack to make requests that do not trigger it, and in some cases easily automated for that Software that give back in the response header the throttling values being applied.
Check request origin (although can be spoofed)....
Yest it is easily bypassed, but why not? It will be one more layer of defense that filters out some dumb automated scripts/bots.
Also if the site is SSR, could it just be protected by the server's IP?
No matter if a SSR site or any other type of app, when used from a mobile phone the IP address can change during the load of a page or mobile app screen, because when the phone switches between masters the IP will change. Also to bear in mind that in an office or public wifi all the users on it will have the same IP.
The use of it as a blocking measure on its own needs to be carefully evaluated, and normally requires fingerprinting the request in order to reduce the risk of blocking other valid users sharing the same network.
I would use it very carefully to avoid/block/throttle requests only when I could establish that hey are known bad IPs, that you can collect from your own requests history and/or from public datasets.
WHO IS IN THE REQUEST VS WHAT IS MAKING THE REQUEST
A common misconception around developers of any seniority is about not being aware that the who is in the request is not the same as what is making the request, therefore we will first clear it out...
The Difference Between WHO and WHAT is Accessing the API Server
While your API is not using user authentication is important to be aware of this distinction in order to better perform informed decisions around the security measures to be adapted in the API server.
I wrote a series of articles about API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in more detail the difference between who and what is accessing your API server, but I will quote here the main takes from it:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
The best way to remember the difference is to think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.
DEFENDING THE API SERVER
My question relates to how one can protect as much as possible and slow down abuse of a public accessible API...
For Mobile APIs
For an API serving only mobile apps you can use the Mobile App Attestation concept as I describe in my answer to the question How to secure an API REST for mobile app?.
For Web APPs
For an API that only serves a Web app I would recommend you to read my answer to the question secure api data from calls out of the app?.
DO YOU WANT TO GO THE EXTRA MILE?
anything else?
It seems you already have done some research but you may not know yet the OWASP guides and top risks.
For Web Apps
The Web Security Testing Guide:
The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
Just for a quick answer
I can suggest at least one via solution which is to use an API Gateway (like Kong, Express Gateway or AWS API Gateway, etc.).
The API Gateway allows you to create API consumers (e.g: buyer mobile app, seller mobile app, buyer TV app). For each API consumer, an auth key (or even OAuth 2.0 credentials) will be generated and asigned respectively.
You then can use the auth key or OAuth 2.0 credentials (ID and secret) to access the APIs securely (even for the public ones, as API Gateways will only allow access from valid API consumers).
How about request from web?
You can configure API Gateway to detect requests from web and instead of using auth key or Oauth mechanism, it can use domain white-listing CORS protection mechanism.
How about user access token (generated from successful login)? Any conflict here?
IMHO (emphasized), after getting user access token (e.g: a JWT), for every authenticated-user-only requests you will send both API Gateway auth key token user auth access token. Referencing to Exadra's answer above, we can consider API Gateway key is to verify the "what" (mobile app) while user access token is to verify the "who" (login user).
I am trying to be sure that I understand it correctly:
Is OAuth a bridge for only third party authenticator those so common like Facebook, Google? And using it improves user experience in secure way but not adding extra secure layer to Django login framework? Or only Authorization Code grant type is like that? Can I take it like this?
What is OAuth?
According to RFC 6749:
The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
behalf of a resource owner by orchestrating an approval interaction
between the resource owner and the HTTP service, or by allowing the
third-party application to obtain access on its own behalf.
Essentially, it is an authorization protocol used to share permissions between multiple applications.
If you decide to implement OAuth, your application will be the one to allow other services to programmatically view your users' data and act on their behalf, if needed.
Whenever an application requires access to another service that you use, it probably uses OAuth to perform those actions. (e.g. When games used to ask us to allow posting on Facebook on our behalf.)
What OAuth is not?
By looking at your question, I feel like there's a misunderstanding of OAuth.
OAuth is not a bridge for third-party authentication methods. If you are looking for this type of authentication mechanism, you should take a look into Single Sign-On (SSO). For Django, you can use django-simple-sso.
Does it enhance security?
Depending on the use case, yes, it can enhance security.
If your application needs to exchange information with other services, it is a good practice to limit what these third-party services are able to do in your app, feature and time-wise.
Let's say, for example, that your user needs to give permission to another application to gather information from yours:
If you were to use the old-fashioned e-mail and password combination method, these credentials would be exposed in case of this third-party service had a data breach.
Using OAuth on the other hand is much more secure, as the credentials stored in the server would not contain the user's password and have very specific roles, apart from being easily revoked.
If you have a Django app I would say that you don't have to implement OAuth - you should be fine with any login functionality Django offers.
OAuth is commonly used when different services talk to each other. These don't have to be third-party services, they can belong to the same party. For example, when you have a Single Page Application or a Mobile App that want to call your backend API to get some data. Then it's better to use OAuth as it is a standard and it helps you to implement authorization in a secure way.
When you think about "login with Google/Facebook", what you actually want is an SSO solution (Single Sign-On). That solution is very often implemented with OpenID Connect (OIDC), which is a protocol built on top of OAuth. Still, you can use just OIDC to log a user in with Google, get an ID Token, and then be able to authenticate the user to your Django app based on the ID Token from Google. You don't need OAuth for that (in the sense, that you don't need to get access tokens from Google, you don't need your own Authorization Server, and you can rely on cookie-based sessions).
I am developing an app that creates a public Spotify playlist for a user who has given proper authorization to do so.
I am using Flask and Python requests library to accomplish this, but after I've sent a few consecutive POST requests to get an access token from Spotify (using authorization code obtained from previous logic), it begins to fail. I am referring to Step 4 of Authorization Code Flow from this link: https://developer.spotify.com/web-api/authorization-guide/#authorization_code_flow
I know the authorization code is valid, because it doesn't fail for the first few times I run the request (maybe 5-10 times).
When I print the response from the POST I get the following:
{'error_description': 'Authorization code expired', 'error': 'invalid_grant'}
I assume I am not using the authorization code fast enough to get an access token (after repeatedly failing on code logic before the access token POST request, I guess?) but how am I supposed to reset and refresh the authorization code so I can keep making requests repeatedly? Any info on how long I am disabled and generally good programming practice to avoid this scenario?
When you use the authorization code to get your access token, you will also get a refresh token back in the same message. Use that refresh token to request new access tokens, when the access tokens expire.
How to use the refresh token is written on the same page you linked to, just a bit further down: https://developer.spotify.com/web-api/authorization-guide/#request-access-token-from-refresh-token
I agree that this is not the easiest to understand, but there are good reasons for all these things. It is also a standard called OAuth2, which many websites use to let users authorize apps to access their data, so it is useful in a lot of places.
In this specific case: "why do I need a refresh token to get an access token, I already have an authorization code to get an access token?", it is because the authorization code has leaked to the outside because it was returned to you via the user's browser.
An authorization code is obtained when the user grants permission for the third-party application (the Client). As per OAuth's 2.0 specification the authorization code must be used once and it's recommended that it have a maximum lifetime of 10 minutes to mitigate security flaws.
Read more about authorization code here:
https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2
On the other hand, instead of boring the user to go through all the OAuth 2.0 dance again (to authenticate and to grant permissions), the server side of Client application can use Refresh Tokens to ask for a new token when it's expired.
More about refresh tokens can be found at section 10.4 of OAuth 2.0 spec.
https://www.rfc-editor.org/rfc/rfc6749#section-10.4
I'm creating a web based service that I want to expose as a REST API so that developers are able to create apps using it. I want developers to be able to create/manage user accounts and authenticate through API. How to handle this? OAuth or something else?
I'm using python,flask,mongodb for this.
We have settled on the following, using OAuth 2 (which is much preferable to OAuth 1). In particular we are using the resource owner password credentials flow. As to how to integrate it into our RESTful service, here is the idea:
The initial resource, when hit by an unauthorized user, returns a 401. The body of the 401 contains a single link, with rel=oauth2-token. (How you signal links depends on your media type; we're using HAL, but you could use even just the Link header.)
After the user authenticates, he returns to the initial resource, sending in his Authorization header the bearer token returned from the OAuth 2 process. At this point, we return a 200, with all the normal links available.
We don't expose account creation, but if you wanted to do that, I would do so with another link available to unauthorized users in the initial resource. That link would have a custom rel since it is specific to your application, e.g. rel=http://rels.myapi.com/users
Good RESTful design would indicate that the link with this rel points to e.g. http://myapi.com/users, and that consumers of the API do a POST to that endpoint, which returns to them the new user resource with a Location header pointing to the newly-created user resource at e.g. http://myapi.com/users/username. (User resources themselves would of course be another rel, distinguishing between the singular user resource and the plural users collection resource.)