API or put the logic inside the app? - android

I'm busy building an app for android. When it's properly received by Android users I would like to expand to iOS.
But, before we get there, I first want to make the right choice. So my question, what to do?:
writing all the logic inside the app and use Cognito (https://blogs.aws.amazon.com/security/post/Tx3LP54JOGBE0AY/Building-an-App-using-Amazon-Cognito-and-an-OpenID-Connect-Identity-Provider) to access the data from DynamoDB
or let my app connect with my own API which handles the validation rules, which I then connect with DynamoDB database (don't know or API -> Cognito -> DynamoDB is a better solution, didn't really used it yet so...).
Now we all know about those issues where hackers built ways to bypass certain validation rules (as far as I read, most commonly by decompiling the app). I really want to avoid that!
So what do you experienced Android developers use? I know the answer seems obvious. But the reason I ask this is because I would like to avoid having my infrastructure, which I need to update etc. But to be able to register users, without the need of an third party which supports OpenID like twitter, facebook or Google, AND secure my validation rules, it seems like I have no choice. Or do I?

If you are targeting multiple platforms, it's usually best to conduct the majority of your business logic in an api outside of the app. It reduces code duplication and if validation is done at the api level, it limits the ability of malicious users to bypass validation rules.
With that said, running your own api doesn't necessarily require running your own infrastructure. Two AWS web services that could help are Amazon API Gateway and AWS Lambda. Registering your users can be done using Amazon Cognito Your User Pools.

Related

When to use cloud functions for Firebase real time databse?

I am not clear with architecture of using Firebase for Android apps. Can you make everything from client side without using Cloud Functions, since it is possible to access database with functions in java. Is it used only for security purposes to restrict client from making problems?
Most functionality can indeed be performed directly from the client-side app, using the Firebase SDK for your application platform. And whenever this is possible, I highly recommend implementing it this way.
But certain types of functionality don't lend themselves well for performing directly from the client. They typically fall into these main categories:
The operation requires privileged information. For example if you want to send push notifications to your app users, you will need to specify the FCM server key. As its name implies, this key should only be used on a server you control, or in an otherwise trusted environment, such as Cloud Functions. This same reason also applies to things like interacting with payment gateways, and many APIs in the Google Cloud Platform that require server-side API keys.
The code of the operation itself is a privileged operation. For example you'll often find this in games, where you want to validate that the user isn't cheating. If you put this code in your app itself, a malicious user can see it and use it to circumvent your detection. By moving the code into Cloud Functions, the users of the app can't see the code anymore.
The code requires more "power" (CPU, network, memory, disk space, battery) than you can rely on being available on your user's devices. Since Cloud Functions run in Google data centers, they are always connected to mains power, they have a reliable CPU, a great network, and configurable memory/RAM disk space.
Another advantage is that Cloud Functions are the same for users on any platform that you target. Say you have a complex algorithm that you want the users on Android, iOS, and Web to use. If you implement the algorithm in Cloud Functions you only have to implement it once, and then call it from each platform, instead of having to implement the algorithm for each one.
I also recommend that you check out the list of use-cases in the Cloud Functions for Firebase documentation.

Google cloud storage with app engine

Its driving me nuts,somebody pls help me out here.This google cloud stuff is confusing me.I m little bit off here,something is missing in my understanding.I want to use cloud storage.Now I have a default Android Studio Project which has an android client,an app engine backend,consisting of entity,endpoint,library for client etc and A WEB CLIENT.While going through the google cloud storage doc, I found the following-
Google APIs Client Libraries
Google Cloud Storage Client Library
Google Cloud Storage API
Google Cloud Storage JSON API Client Library for Java
I m still not sure what each one does actually.I dont know how to implement cloud storage in my android client.
If I use cloud storage why do I need app engine backend app? I dont need API for my backend,right? I can directly consume my bucket using Google Cloud Storage JSON API as we do using Volley. Am I missing something here?
Is there any "hello world" tutorial on how to use cloud storage from android client/app or can anyone help ?
If you're 100% sure that you don't need any back-end logic, and never, ever will, see Using Google Cloud Storage JSON api in android for direct Android <-> Google Cloud Storage operations.
Usually, in the course of a successful app's lifetime, some logic on the back-end is eventually required (e.g to deal with different versions of clients -- not all update in the same nanosecond:-), so it's normally more prudent and future-proof to have the front-end go to an App Engine back-end that can apply whatever logic is required besides providing access to Cloud Storage.
At version 0.1 the amount of logic required may be very small (though usually at least some kind of authentication) but if the application is successful likely new versions will be required and the back-end will be able to evolve to deal with that.
Then in a comment you ask:
As far as I have understood the appengine, if I need to store data in
NoSQL datastore, then I can make a backend with endpoint support which
will in turn consume my Restful API.
A more common arrangement is to have the back-end supply a restful API for the front-end to consume; and, that's what Cloud Endpoints can do for you (though you could design and implement that restful API in many other different ways, if you'd rather).
I mean, can I/should I consume the cloud storage rest API from within
my backend endpoint, which itself is used to call my own rest API?
One robust architecture is based on separation of concerns. Let the front-end running on Android concern itself essentially with the "human interface" part of your overall application -- presenting data clearly and usefully, interacting with the user.
The front-end can delegate just about every other concern to the back-end, including both storage and most aspects of app-specific logic concerned with what to store where, whether to allow access (of what kind -- read/write or read/only) to certain data depending on authentication of the user, and so on.
This delegation can take advantage of Cloud Endpoints, or, you could choose to design and implement it differently (e.g producing and consuming the app's REST API via different frameworks).
Why do I need backend logic to deal with different versions of
clients?
You'll need that, for example, if and when a new version of the client wants to store and retrieve more data than older versions did -- for example, in some future version you may decide it can be useful to add GPS location data, or optionally multiple photos or an audio snippet, etc, etc, which were not used in previous versions. (It's hard to be specific of course without any idea as to what your app is all about, but in general there's always something that you didn't do in early versions and want to add to some future one:-).
In such cases, the back-end needs to know what bits and pieces of data, exactly, to expect from the client, and conversely which ones to serve back to the client -- and those crucial aspects will then depend on the client's version; and without back-end logic to mediate, smooth seamless transition between old and new clients won't be feasible, particularly during the transitional period when some clients have upgraded to the newer version but others are still stuck on the old one.

mobile apps: restful api or sdk dynamodb

I'm building my first app which uses an external database for storing data..
And I'm struggling with the following question:
How to connect with my database: use the Amazon DynamoDB sdk for Android or create a restful api based on NodeJS on my own server, which passes the data to DynamoDB?
I'm very new to this and when I look over the internet I see amazon suggesting to use the SDK.
The only problem is, if I want to change the data structure in the feature, what kind of problems will my users experience with the current versions of the app? And is it safe to save my Amazon keys inside the app (cause people may be able to decompile the app)?
On the other hand, I do have to pay for the extra server which handles the connections between my app and DynamoDB. So... is it worth it?
So I'm quite struggling with this.... What do you guys think?
I would go for direct access from your mobile application to DynamoDB.
This would allow you to scale your application much easier : you do not need to maintain, operate, secure a middle layer, AWS does that for you. You will also save on the cost of running your couple of NodeJS servers, load balancers etc ...
You should not store access keys / secret keys in your application but rather use AWS Cognito Identity service to dynamically receive access keys and secret keys for your user session. These keys will be limited in scope to whatever permission you define for your Cognito users and limited in time (default is 15 min)
Cognito works with backend identity providers to authenticate your users (Facebook, Google, Amazon, openID connect or your own backend) and can also work with unauthenticated users.
More about Cognito : http://aws.amazon.com/cognito/
More about Cognito ID for Android Mobile Applications :http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html
I'm not sure that the accepted answer is complete because it does not acknowledge use cases, and it does not address the question asked of "what if I want to change the data structure." Well, if you have outdated clients, and change the data structure of the documents in your nosql database, then those clients will not be able to access it. I don't believe DynamoDB offers a middleware platform to support this kind of old-to-new model adaptation. You'll have to force an update to your clients.
In fact, there are many operations beyond user-based permissions (which Cognito does do well) like this that you might need middleware for. Perhaps you want sorting logic to occur at request-time, and not maintain a copy of that sorting logic in every client application.
The question of "is it worth it" probably depends on the complexity of your application and your users' relationship with the data (ie. if the presentation layer basically just wrapped data -- then directly access DynamoDB. If you your presentation layer is not just wrapped data, then you should probably use custom middleware). In truth, I stumbled upon this question while running my own cost-benefit analysis, and am not sure which approach I will take. Another major factor of mine is that I might choose to switch database solutions in the future.. this will be more challenging to update on every client, if my clients are directly accessing the DB.
The one certain conclusion I've reached is that you should use middleware somewhere in your system, such that you can decouple your database vendor from either the client logic or the server logic as much as possible, eg. in a mobile app:
writeToDatabase(Data data){writeToDynamo(data);}
To achieve this, AWS suggests using Amazon Api Gateway as a proxy for AWS services, and even has premade configurations for Amazon API Gateway to behave as AWS service proxy.

How to avoid Rest API abuse in Android?

We have developed a service with REST APIs and an Android app that leverages it. We currently don't require our users to authenticate.
We would like to implement a simple mechanism to prevent the random person from invoking the APIs from outside of the scope of the app, mainly to avoid abuses that would spoil the data that we compute.
I stumbled upon this url where they suggest to have authentication enforced by having the server and Android client to share a secret and use that to compute an HMAC to pass along with the request. They claim that they use this approach in Amazon (I have no experience with Amazon AWS yet).
I'm considering to proceed as follows:
store a common secret in the Server and in the Android app (any good idea for obfuscating it, besides using ProGuard?)
Have client and server to communicate over plain HTTP (we don't need confidentiality yet and we will save some CPU) and use the HMAC method to authenticate the calls as "coming from a legitimate Android client".
From time to time we can update the secret (perhaps at each new version of the app).
If in future we will need confidentiality we will enable TLS for the relevant REST calls.
Do you think that this solution would work? Is anyone using something like this? Alternatives? Advices?
Thanks.
I am not a security expert.
Your solution sounds fine to protect you from "the random person", but you are still vulnerable to a dedicated attacker. Anything stored on the client can be dug out and used against you. ProGuard will dissuade a casual attacker, but against a dedicated attacker it's just a speed bump.
Nobody here is going to be able to tell you if that level of security is good enough, because it depends a lot on the specifics of your application. The final decision should rest with the product owner.

Should Android apps with a server side component access Facebook directly?

If I am building an Android app that uses the Facebook SDK and also has a web app that has most of the same functionality, how should the Android app handle social actions? Should it directly make requests to the Facebook API through the SDK or should it post to the web app server through my own API and allow the web-app to make the request to Facebook on behalf of the Android app? Most of the Facebook for Android examples use the former approach however none explicitly discuss the best practice when there is a web backend that will have the same social functionality as the Android app.
I've been putting my mind into a similar problem before. It was a PHP app, but essentially the design choice was to either put the FB-interaction into the frontend (JS-SDK) or into the backend and proxy it (PHP-SDK). Sadly haven't found much guidance either, so I had to make up my own mind.
As so often there seems no per-se answer, it depends on what you are doing with FB and how deep it is integrated into whatever your app/webapp/backend are doing. Is your Android otherwise more a client-side app or does it rely on other features delivered by the web-app via web-service? Is it somehow integrated with users actions that are dispatched to the backend, or does it just offer some additional gimmicks (e.g. 'Like' button, anything in the lines) Are you using the SDK to authenticate and pull user related data from FB (email, name) and does that information play a role in your backend?
As I see it, it boils down to the following:
Direct communication with FB is a lot simpler to implement as you won't have an additional layer between your app and FB, i.e. proxy code, etc. So if FB is just loosely coupled it's likely the 'good-enough' option.
Patching FB from frontend to backend can get nasty - especially if you want to authenticate via FB it's kinda complex at first. However, you'll have all FB logic in a single place, shared by Android-App and Webapp, so it's obviously easier to maintain later and better to integrate with other interactions your backend might be offering.
Hope that provides some value, would be eager to see other opinions too.
Well I think both approaches are correct but the choice depends on mostly what you already have in place on the server side and if you are planing to use the same functionality from different apps like (Android,iOS, Windows Phone apps). In that case it makes sense to just get user token with permissions you require on the front end and let the web server talk to facebook using that token. You could even save this token for the user so they don't have to give permissions again if for example you have web registration and app registration. In our app we are using this approach since there are basically five front ends (Android,iOS, Desktop,Mobile Web,Full Web) this way application developers just get token using sdk on there platform (you have to use tokens and not user name, password because of facebook rules for security). On the other hand if all Facebook communication is used only inside your app and the server doesn't need to know much about it put api calls in the app.
In my opinion, it is best to use the available SDKs/APIs for each given platform instead of trying to write your own centralization and use a single library. Since you are specifically interested in how the Android app should handle social interactions, I suggest using the Facebook SDK for Android.
While it does increase the size of the code you must maintain and the SDKs/APIs you must learn as your list of platforms increases, the most important factor for this approach is the user experience. By sticking with the native libraries, and growing your app as those libraries evolve, you will be providing your users with an experience that they are most likely to be used to. They won't have to learn how to use your app, but will be able to make posts, update their status, and look at their friend list using controls that they are accustomed to using. Additionally, you will be able to take advantage of specific platform functionality (in the mobile case, such as having your app post to a users feed in a way that promotes your app: https://developers.facebook.com/docs/tutorials/androidsdk/3.0/games/feed/)

Categories

Resources