I am using Django and we are planning on opening some of our API for 3rd party usage.
Till now we have been using DRF along with session authentication for our Django Web App and DRF with JWT for our Android application.
What I would like to know is whether the call is from our own app (webapp/android app) or from 3rd party apps (they can call from their own applications, which can be other webapps/phone apps). Is there any way this can be distinguished? We want to count the no.of 3rd party API call to our server.
Your android app can add header User-Agent with app version. So you may distinguish requests. However it is not very reliable - as any web client can send such headers. Here you can sign your requests. Take URL add some secret value calculate md5/sha2 from this values and add to request.
Protection is based on idea only you know secret value. It is ok for non-critical tasks but may be risky for financial apps.
Related
I have an Android app where I use Firebase Auth API to confirm the user's phone, also I have my own server to store user data.
I'm planning to make cross-platform app using kmm. But problem is that Firebase Auth API require call setActivity(activity) method to be called, which depends on the Android activity.
I would like to share the authorization code between Android and iOS. Are there any solutions that allow you to use common Kotlin client side code or Kotlin server side code to do this?
I ended up have implemented 2 endpoints (/send_code and /check_code) on my server and have used a third party API to send SMS. An important part of the implementation was the IP limit on the number of requests, since all third-party APIs are paid.
I had created an Android app that requests resources from the server using Rest APIs. Now how can I check on the server side that the request is from the app and its not from the Postman.
For example,
I am using the following endpoint to get data from the server.
https://api.example.com/get-data/{id}
Now, this endpoint is also accessible from a browser. Therefore I want a solution to make the API in-accessible by all other means. ie. It should be only accessible from my android app instead of any browser, Postman or an android app that is not built by me.
In other words, I want my android app to send a special piece of information that helps the server to authenticate the app.
Besides this, I am also concerned about someone to decompile my APK and take out that information to make API requests.
Note By special information I mean a security key or a mechanism to generate that key.
I am looking for something like the "origin" header that is set by the browser by default and no one else can change this header even the developer of the website. Does anything like this exists in android?
You need to implement an API token, that behaves like a password for your API.
A simple way of doing this is using the Bearer Header with the token value to come from the API and every request you send via your app should include this token as a header.
An example is the Slim 3 Token Authentication which does this for Slim 3 Framework APIs. IF you are using laravel API, try https://laravel.com/docs/5.6/passport
TL;DR: I would like a native (already logged in) Android application provide auth tokens to third party applications installed on same device. I would like to use as much as possible of standard spring-security-oauth2 code as I am no OAuth2 expert.
Long version:
I have a system consisting of:
an Android client application
a central web application exposing some data via REST APIs currently secured by HTTP BASIC. The central app holds a repository of user accounts.
this all works well in an isolated environment.
Turns out third party Android app providers would like to integrate with my system. Actualy no REST API calls will be made - the only purpose of the integration is joined user accounts.
I have created an OAuth2 (spring security based) authentication server that third party apps can use - this way the users can use same credentials both in mine and third party apps.
Thing is: my users still have to enter the credentials at least once for each app. This is cumbersome: my users are kids - they often do not remember or are simply not able to input credentials.
Instead of forcing third party providers embed WebView in their application and handling OAuth2 calls to my server I would like them to call my application which is conveniently already logged in. My app would handle the actual authorization UI (via native activities) and respond back to calling app with proper tokens.
The main problem is: I do not know how to start.
Can I force spring-security-oauth2 to use JSON only? I see that the most important authorization endpoints generate html on the fly.
Do I have to create my own endpoints handling this approach or any standard OAuth2 flow would do?
I have a simple Google App Engine backend (written in Python) for an Android client. All the backend is responsible for is accepting a key and returning a value; it is a classifier in general, implemented simply by looking up the key in a Cloud SQL table, though this specific behavior will change in the future.
The backend and client communicate via Google Cloud Endpoints. I want to restrict access to my backend's API to only accept requests incoming from my client, and am wondering if OAuth 2.0 is really the way to do this.
I don't need any contextual or extra information from the user, and as such, don't want to have user action to grant any type of authorization. All I need to do is be certain the request came from my app. I was considering simply generating a static key and hardcoding it in my client and backend, but I thought there must be a more elegant way to do this.
TL;DR: How can I restrict access to my backend only to my client/app without needing user context/input, by OAuth 2.0 or otherwise?
I don't know if the OP solved their problem but I am posting this here for others. I have wasted quite a few hours on this particular issue.
Steps :
1.Create an oAuth 2.0 client ID for your Android client.
2.Specify the Client IDs in the allowed_client_ids argument of the endpoints.api. In this case (Android), supply both its Android client ID and a web client ID in allowed_client_ids.
3.Supply the audiences argument as well in endpoints.api which is set to the web client ID.
4.Add a user check to the protected methods.
5.Redeploy the API backend.
6.Regenerate the client libraries.
I have a pre-existing iOS & Android app, that I'm making an update for that includes a RESTful services API and Facebook login for user authentication. The general flow of the app is:
Users "logs in" to my app, via Facebook's SDKs, which return an access token to my app.
App calls a RESTful service, including the Facebook access token as a parameter (using HTTPS and SSL)
Service that is called, sends the received access token (and app secret stored only on my servers) to Facebook to verify who the user is, and performs actions based on that. Facebook is set to require app secret from server-side calls.
My app has gained popularity and has several clones already, and I want to prevent these clones from being able to use my RESTful API (as I am sure that they will try to do when I release the update). Let's assume that the clones are smart, are using the same Facebook access tokens that my app does (if this is possible), and are following a similar pattern & frequency of calling the API that my app does.
Is there anyway to ensure, or nearly ensure, that calls to my services are coming only from my app, and not the clones?
Thanks in advance!
You can do this by including a signature in the request, and verifying it.
App Side:
do something like: signature = md5( md5(url + data) + MY_RANDOM_KEY)
append signature to the data, or url, etc.
send call to REST api (as usual)
Server Side:
extract the signature from the body/url (and remove it from there).
calculate what you think it should be: signature_should_be = md5( md5(url + data) + MY_RANDOM_KEY) [keep in mind you've removed signature from url/data so that you get url/data in its original pre-hash state]
verify that signature and signature_should_be are equal
Doing this, along with SSL, should make your API secure enough.
You could do as Tommy Crush suggests and add a secret inside you application. But if you are up against clever opponents, this probably won't help. The attackers can either decompile your application or try to simply reverse engineer your signature algorithm.
It is important to remember that anything stored within your application should be thought of as already compromised, as an attacker can decompile your app and scour through your code as much as he/she pleases and extract anything he/she wants from it. You cannot rely on anything in your application to be safe inside your app, since an attacker can extract it from your app into their app.
It is important to note that you are using trying to use OAuth for authentication, which is not intended for. It is simply meant for authorization, which is not the same as authentication. Authorization simply gives you access to a resource, but does not tell you who accessed it, which is the problem you are facing. To authenticate your users as your real users (or as close as you can get), you would need to add a login service for your service - something like rolling your own OAuth-server, or similar. Then you can decide who can access the resource, which in this case is your RESTful API :)
If this is more work than it is worth, then Tommy's scheme is a good alternative :)
The de facto solution for authentication on restful APIs like Twitter and Facebook use is the OAuth mechanism.
You can find more details here: http://en.wikipedia.org/wiki/OAuth.
OAuth is supported from the majority of the languages with external libraries.
On Android for example there is the https://github.com/wuman/android-oauth-client library.