How can i cache an access token embedded in a redirect url? - http

I'm trying to make use of an API from a local bank, which uses OAuth2 as their authorization method.
The authentication process is as follows:
User clicks on button, webview within application is launched, and user is directed to
URL A: "https://{API URL}/{constant key}/{redirect url}"
Then they have to authenticate with their banking credentials, and the next page prompts them to key in an OTP.
If this is successful, the session token will be embedded in the redirect url as such:
Redirect URL: https://{redirect url}/{access token}/{type}
How can I cache or store this access token as a variable in my flutter code so that i can use it for other API calls? I am currently using flutter webview plugin and i have no issues launching the webview and reaching the different URLs, but i can't seem to find a method to store the token.

For local storage:
You can use https://pub.dev/packages/shared_preferences which uses the native counterparts for storing preferences. Its basically a key/value store.
Wraps NSUserDefaults (on iOS) and SharedPreferences (on Android),
providing a persistent store for simple data. Data is persisted to
disk asynchronously. Neither platform can guarantee that writes will
be persisted to disk after returning and this plugin must not be used
for storing critical data.
Another alternative would be SQLite with this package: https://pub.dev/packages/sqflite
SQLite plugin for Flutter. Supports both iOS and Android.
You can of course also use the File I/O capabilities of Flutter as described in the docs:
https://flutter.dev/docs/cookbook/persistence/reading-writing-files
Another route is by using a cache manager package, which will use the cache of the app together with SQLlite in the background. Might also be a solution but files can be deleted by the OS at any point in time. See the package at: https://pub.dev/packages/flutter_cache_manager
for remote storage:
Then of course, as most of the flutter developers use firestore (https://firebase.google.com/docs/firestore) or cloud storage (https://firebase.google.com/docs/storage) from the Firebase Brand, you can easily chose to go this way. Of course then the data would be in the cloud. Dont know if that meets your security requirements.
Most likely i would prefer going the local persistence way with the first mentioned methods.

Related

Firebase custom auth in server-to-server scenario

I need to implement a scenario where, after a file is uploaded to Google Cloud Storage, a function is triggered and processes the file. In this case, processing basically means sanitizing the file, storing it into Firestore and making it accessible via another HTTP-triggered function (a REST API of sorts).
Both user-facing ends of this process (a file upload and HTTP function) need to be secured. The process will be used in server-to-server scenario: one side is going to be a backend written in either Node.js or .NET, the other will be my Firebase solution (Cloud Storage and HTTP-triggered function as per above). In Firebase, I am going to maintain a custom set of users that should have access to the system - my idea was to use a simple system where each user will have a client id and a client secret (basically an oAuth client credentials grant type).
Based on what I read online, an only option to implement this is to use [Firebase auth with custom tokens][1]. I found lots of examples online on how to do that, but it was always about client-to-server scenarios (e.g. a Javascript web app talking to REST API). Server-to-server scenarios were not mentioned anywhere and indeed, I am unsure how to go about implementing it - I can call auth.createCustomToken(uid) just fine in my HTTP Firestore function, but there seem to be no server-side libraries I could use to call auth.SignInWithCustomTokenAsync(customToken).
To sum it up:
How can I use Firebase auth with custom tokens in server-to-server
scenario, where I need to sign in using a previously generated
custom token from a server environment?
If it is not possible,
what's the other alternative to securely implement the
above-described architecture?
I've contacted Google Support and if anyone else is struggling with this, in server-side scenarios, recommended approach is to call signInWithCustomToken endpoint in Firebase Auth REST API.

How firebase Admin SDK differs from firebase console web page?

I'm developing an android app with firebase as a backend and I heard a word named Admin SDK. I had searched for it and found it is used to manage data.
But I have a doubt that firebase provides a console webpage (console.firebase.google.com) to manage data, but why there is a separate Admin SDK?
Can someOne please explain...
The firebase admin SDK provides a simple and easy way to modify firebase settings and data using API calls.
For example, you might ask: why should you even have a regular SDK to store data? After all, you can store and save data directly from the web interface. It is, however, simply not secure or practical to have users update their own data each time using the console.
Similarly, the admin SDK is just like the regular SDK but with administrator permissions. For example, it allows you to bypass the rules set up using your firestore rules. The Firebase admin SDK is meant to be used on your backend - so you know it is running trusted software. You know that it will act the way you expect it to, unlike code running client-side that can't be trusted.
For example, let's say that you want to be able to delete a user's post if certain conditions are met. The user will make the request to your server, and it will check if the conditions are met, and then delete the post using its admin privilages. Sure you could technically automate this using firestorm rules, but those can be quite cumbersome and might not work in more complicated examples.
You can also even use it to integrate with other applications like connecting your app to a moderation tool or a curse detector that can't or shouldn't run on the client's device.
Is your question is why does Admin SDK exists?
There are several administrative tasks such as deleting users, listing collections and many more which the client cannot and should not be able to do.
Firebase Admin SDK has admin access to your Firebase project's resources.
It does not obey any security rules and can read/write any of your database, storage bucket..
That is why you must use Admin SDK in a server (or cloud function only). Although I feel Firebase Admin SDK is more useful if you use your own servers and authentication method. If you are using a custom server then:
It can be used to generate custom token so you can authenticate users using your own method (maybe legacy auth system) but still use Firebase Authentication to handle the auth tokens thereafter.
If you use your own database (and not any from Firebase), the Admin SDK can verify the ID Token sent by client and get identity of that user. Thereafter it's could be a simple if-else statement for you to decide if the user has access to the request resource or not.

Firestore and data encryption in Flutter

Tl;dr.. I'm making a todo app where I store data in Firestore, and I don't want anyone to see it not even the devs from firebase console. I found many encryption pkgs that do the job, like: encrypt. My problem is how to I handle the 'encryption key'. I don't want to keep it local because in my app user can access it's account from different devices, so if the key is stored locally they cannot decrypt thus retrieve their data (notes) from the other device (i hope this makes sense). So, do I send the 'encryption key' to firestore in a seperate collection or ... how should I approache this ?
You could store the key with Firebase Remote Config and retrieve it in the app when you need it.
Firebase Remote Config is a cloud service that lets you change the
behavior and appearance of your app without requiring users to
download an app update. When using Remote Config, you create in-app
default values that control the behavior and appearance of your app.
Then, you can later use the Firebase console or the Remote Config
backend APIs to override in-app default values for all app users or
for segments of your user base.
Check out the documentation for the flutter_remote_config plugin.

How to use GoogleDrive from Android app using FireBase Auth UI?

I have implemented Firebase Authentication in my app, using the Google Provider and the "https://www.googleapis.com/auth/drive.appdata" scope so my app can access its application folder within Google Drive
This part works fine and I retrieve the FireBaseUser once the authentication completes
What I now want to do is to access my app storage on Google Drive, but I don't know how to do this using the result of the current authentication
I tried to follow this: https://github.com/gsuitedevs/java-samples/blob/master/drive/quickstart/src/main/java/DriveQuickstart.java
But this doesn't work on Android.
The main issue is how to create the Credentials object
Do you have any idea on how to initialize a Drive.Builder instance so I can write/read to the app Google Drive folder?
Thanks
This cannot be done directly, because the Firebase & Google login are not the same, even when having logged in to Firebase with a Google account. On Android one meanwhile only has the "last logged in Google account" available for the user's Drive (the one on the device, which has nothing to do with Firebase Authentication, where Google may only be used as an "Authentication Provider").
So there are generally two options available to you:
Grant a GCP service-account access to Drive API and use Cloud Functions to access it.
Instead use Cloud Storage, which is within the Firebase eco-system and is similar to Drive.
I could also think of a combined solution approach, where users would use Cloud Storage (together with Firebase Authentication) and having a Cloud Function which uses a service-account, which eg. copies or moves uploaded files into a folder your Drive.
Concerning that (obviously server-side) Java example, the credentials.json clearly hints for a service account... and this is exactly where you can obtain this file from. However, for Android this is pretty useless - because it has major security implications, to package service-account credentials in an easy to de-compile package and distribute it on the WWW (to everybody). The Google Play Store likely would not permit you to publish or even upload that, because there are security checks in place. You could in best case only deploy that code as App Engine module, but not as an Android module.
Sorry for having destroyed your delusions and for not being able to provide a ready-made solution for 500 imaginary internet points, which pay nothing - but at least I can tell what is technically possible and what isn't - which effectively might save you lots of time, trying to accomplish the impossible.

Can somebody get Firebase credentials from my apk and use them?

Can somebody else get the Firebase credentials from my APK and use them? Is this prevented by adding the SHA-1 keys for Android?
If it is prevented, what do I need security rules for since only code from my app with my SHA-1 can manipulate database at all?
If it is not prevented, can somebody else use my Firebase database as long as his requests fit the security rules? (Write 2nd client, which actually cannot do bad things but should not be allowed at all.)
Im not sure how I should think about security rules:
A) Protecting data against access and manipulation from bad guys + B?
B) Just a set of rules to keep data in a certain state and prevent my software from doing invalid database request?
A Firebase Database can be accessed via the REST API, or any of the client libraries. The decision about whether a client can or can't do something is entirely based on the rules.
You can even just access the Database URL in a web browser and see a JSON response by putting .json on the end, e.g. https://[YOUR_PROJECT_ID].firebaseio.com/.json
So the answer is definitely B! The default rules in a new Firebase project are that read and write to the database require auth, but you can configure them to provide whatever levels of protection you need.
Take a look at the Database Rules quickstart to see what you can do!
We don't ship the Realtime Database secret (or any other "secret" material) in the json file that gets baked into your app. That file simply contains resource identifiers that allow us to know which resources (database, storage bucket, analytics, etc.) to properly authenticate to (we use Firebase Authentication for these purposes), and we handle server side authorization to ensure that users are properly logged in.
If you are authorizing your requests properly (using Firebase Realtime Database Rules, for instance), your data is secure!
I'd recommend watching The Key to Firebase Security, one of our I/O talks, which talks in greater detail about how this works.
firebaser here
Thanks to the new feature called Firebase App Check, it is now actually possible to limit calls to your Realtime Database to only those coming from iOS, Android and Web apps that are registered in your Firebase project.
You'll typically want to combine this with the user authentication based security that Mike and Ian describe in their answers, so that you have another shield against abusive users that do use your app.

Resources