Should Google OAuth 2.0 access token be stored in appdata, or stored using LsaStorePrivateData for login caching
Where would the best place be to store a Google OAuth 2.0 access token on Windows for login caching? Would it be appropriate to store the access token in %APPDATA%
, or should LsaStorePrivateData()
, and LsaRetrievePrivateData()
be used in a plugin (Storing Private Data)? The general procedure for the app is listed below.
- Get access token from google using googleapis_auth (Installed/Console Application)
- Send google access token to server for verification that the access token is valid and from an authorized user
- If the user is authorized, save the access token to disk, and user performs tasks in the application. While the app is running, the access token is refreshed, and saved to disk when refreshed
- The user exits the application, but doesn't logout
- When the app is re-opened, the access token is loaded from disk and sent to the server for authentication and verification, repeat step 3
Note that the verification of the access token confirms that the access token isn't expired.
do you know?
how many words do you know
See also questions close to this topic
-
WebView2 JS injection returns empty json string
With WebView2 for targeting Windows, I am trying to setup my own context menu. Either by selected text or by underlying element pointed by mouse click.
However, I can't get DOM element by mouse operation or even by byId. I think my JavaScript injection or WebView property setting is something wrong, but not too sure. Can anyone suggest me the resolution?
The version info.
- OS : Windows 10 Pro 21H2 19044.1682
- Visual Studio : Community 2022 17.1.6
- WebView2 : 1.0.1185.39
- Project Property: Target framework=.NET 6.0; Target OS version=10.0.19041.0
Here's the testing code
using Microsoft.Web.WebView2.Core; namespace WinFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); HTML(@"C:\temp\test.html"); } public void HTML(string url) { webView21.CoreWebView2InitializationCompleted += WebView2Control_CoreWebView2InitializationCompleted; webView21.Source = new Uri(url); } private void WebView2Control_CoreWebView2InitializationCompleted(object? sender, CoreWebView2InitializationCompletedEventArgs e) { if (!e.IsSuccess) { MessageBox.Show($"WebView2 creation failed, with exception : {e.InitializationException}"); return; } // subscribe to events we are interested in webView21.CoreWebView2.ContextMenuRequested += CoreWebView2_ContextMenuRequested; // user clicked right mouse to show context menu } private async void CoreWebView2_ContextMenuRequested(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2ContextMenuRequestedEventArgs e) { IList<CoreWebView2ContextMenuItem> menuItemList = e.MenuItems; menuItemList.Clear(); // clear default menu items, like prev, next, property //GETTING SELECTED TEXT string text = e.ContextMenuTarget.HasSelection ? e.ContextMenuTarget.SelectionText : ""; // it works if (string.IsNullOrEmpty(text)) // no text selection, then examine DOM { //GET AN UNDERLYING ELEMENT FROM MOUSE POINT var result = await webView21.CoreWebView2.ExecuteScriptAsync($"document.elementFromPoint({e.Location.X},{e.Location.Y})"); //it doesn't work, just returns an empty JSON text (not null) //var result = await webView21.CoreWebView2.ExecuteScriptAsync("function foo(){return 'foo() gets called';}; foo();"); //for testing purpose, it works //var result = await webView21.CoreWebView2.ExecuteScriptAsync("function foo(){return document.getElementById('table-content'};foo();)"); //it returns an empty result } // TO DO // setup menuItem tree based on the result we got //...... //...... e.Handled = true; } } }
-
site only opens in CefSharp
zaakr.net is a site can be opened only in zaakr.exe application or through android(.apk), when opened in browser u been redirected to https://browser.zaakr.net so u download there application, (.exe) file is using cefsharp as a browser so it can access website, from 2 month i could open it from chromium as cefsharp uses chromium, now i can't access website through chromium for some reason idk, i even made a cefsharp browser myself using visual studio nothing worked all the time i been redirected to browser.zaakr.com, i want to access through any browser that have devtools available for a project, note that application zaakr.exe is still using cefsharp even the older version still can access site. i would appreciate any help, sry for any spelling mistakes, thanks.
-
Subprocess $Env:Path python: The filename, directory name, or volume label syntax is incorrect
I am trying to change the windows environment variables, but I am having trouble doing so.
Before I tried to use
os.environ()
I tried out using powershell commands and adding a string to$Env:Path
which worked, but removing it with:$env:Path = ($env:Path.Split(';') | Where-Object -FilterScript {$_ -ne $Remove}) -join ';'
however didn't seem to remove it being my path I want to add
("FFmpeg:C:\Users\user\AppData\"
) and adding it with+= C:/Users/etc..
didn't see, the way to go.Another way I tried to add vars through the Powershell commands was using
SetEnviormentVariable
and it seemed to work fine but once I restarted my PC the entry I made with it was gone.Sadly though all in the end all my powershell commands didn't work with subprocess. Whatever command it was I was using here I got:
PS C:\Users\Me123> python >>> import subprocess >>> subprocess.run("$Env:Path", shell=True) The filename, directory name, or volume label syntax is incorrect. CompletedProcess(args='$Env:Path', returncode=1)
-
how to change prettier format for react native
my code formatting prettier didn't works well for react native, i don't understand where to config it but it works well with flutter
from this code
import { View, Text } from 'react-native' import React from 'react' export default function App() { return ( <View> <Text>Apps</Text> </View> ) }
it's formatted to this
import { View, Text } from 'react-native' import React from 'react' export default function App() { return ( < View > < Text > Apps < /Text> < /View> ) }
-
How to group firebase data in flutter with DateTime?
I am making a chat application in flutter using firebase. I want to show a header with the date whenever the date changes. How can I group messages in flutter coming from firebase on the basis of date and show a header with the changed date?
I have tried GroupedListView package but I was not able to retrieve the chatmessages successfully.
-
Can you make complete apps using Flutter & Dart or just the UI part of an app?
I'm confused about what Flutter framework actually does, I know that it uses Dart and have heard that both of them can be used to create cross-platform apps.
But Wikipedia defines Flutter as a "UI Framework", so my question is, can you make a complete app (for mobile) which also has backend part (communicates with a database) built entirely using Flutter & Dart and not only the UI part?
If you didn't get my question, here is an example:
Suppose a front-end web developer works on client side programming in his job, and the backend logic is written by another backend developer.
When it comes to mobile app development, suppose as a Flutter developer, your job is to create apps, but does that mean that as a Flutter developer, you'll only write the front-end logic and leave the backend part for another backend developer like in web world? Can Flutter developers also write the backend of an app using only Flutter & Dart? If not, then who writes the backend of a mobile app and what tools/languages/frameworks does he uses?
-
how to get a list of available monitors in windows 10
I want to get a list of available monitors in Windows 10, same as the monitor list shown in the System display settings (no matter whether they are attached or unattached), just like this:
I use
EnumDisplayDevices()
to enumerate all displays, but there is no proper flag indicating whether the display is available.So, how can I do this?
-
Prevent window from being clicked in while another window is open
On Windows, when a window opens on top of another window, the parent window will not be clickable, and will make a "ding" sound and its titlebar will flash. It will do this until the other window is closed. How do I recreate this in Win32?
-
APP_NAME wants additional access to your Google account
What is throwing me off here is the keyword additional. Users are seeing this screen every time they sign in with Google. Shouldn't they only see it once (the first time)?
I'm using the Google 3P Authorization JavaScript Library for websites.
I followed this documentation in my implementation.
It just seems weird to me that the screen says "additional access" but then doesn't list any additional permission requests.
Anyone have any idea what could be causing this? Or is this the expected behavior?
-
gapi.analytics.auth authorize change access_token doesn't work
in the code, I'm using gapi.analytics.auth.authorize function with access_token as shown below:
gapi.analytics.auth.authorize({ serverAuth: { access_token: access_token_one } });
after that, I'm displaying DataChart:
timeline = new gapi.analytics.googleCharts.DataChart({ ... }); this.timeline.execute();
the problem is that when I change the access_token for another user:
gapi.analytics.auth.authorize({ serverAuth: { access_token: access_token_two } });
and do again
this.timeline.execute()
- it uses old, previous access_token (access_token_one instead of access_token_two), so that the access_token is not changed. -
ListTile onTap: Need to Check JWT in Secure Storage and Then Proceed with Named Page Navigation
New to Flutter, and I'm stumped on how to proceed with my App.
My user has already been authenticated via an API call, and the user's JWT is already stored in Flutter Secure Storage (I have verified that the token can be read from storage).
I would like to read the token from storage (before changing routes) to make sure that it hasn't expired. If the token has expired, I'd like to route the user back to the login page using a named route
'/'
. If the token hasn't expired, I'd like to route the user to a named route called'/devices'
.I'm using the ListTile's
onTap;
to call an inlineFutureBuilder
where myfuture:
issecureStorage.readSecureData('jwt'),
. This is working fine.ListTile:
ListTile _tile(String title, int pid) => ListTile( leading: const Icon(Icons.cloud_download_outlined, color: customGreen), title: Padding( padding: const EdgeInsets.only(bottom: 10.0), child: Text( title, style: globalTheme.textTheme.headline3, ), ), subtitle: Text( 'Property ID: ' + pid.toString(), style: globalTheme.textTheme.caption, ), onTap: () => FutureBuilder( future: secureStorage.readSecureData('jwt'), builder: (context, snapshot) { if (snapshot.hasData) return const CircularProgressIndicator(); if (snapshot.data != '') { var propertyInfo = {'pid': pid, 'propertyName': title}; var jwt = snapshot.data.toString().split('.'); if (jwt.length != 3) { Navigator.of(context).pushNamed('/'); } else { var payload = json.decode( ascii.decode(base64.decode(base64.normalize(jwt[1])))); if (DateTime.fromMillisecondsSinceEpoch(payload['exp'] * 1000) .isAfter(DateTime.now())) { Navigator.of(context) .pushNamed('/devices', arguments: propertyInfo); } else { Navigator.of(context).pushNamed('/'); } } } else { Navigator.of(context).pushNamed('/'); } throw Exception('Error: builder is null'); }, ), );
My problem is that my code stops on my
builder:
. I've use the debugger to step through the code and have found that it simply won't continue past this line of code. No error is indicated.Is this a type problem, or maybe I'm using FutureBuilder incorrectly?
EDIT 4/13/22:
I'm using the following
class
to read data from secure storage.import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class SecureStorage { final storage = const FlutterSecureStorage(); Future<void> writeSecureData(String key, String value) async { await storage.write(key: key, value: value); } Future<String?> readSecureData(String key) async { var readData = await storage.read(key: key); print('KEY: $key, JWT: $readData'); return readData; } Future<void> deleteSecureData(String key) async { await storage.delete(key: key); } }
I noticed that this class is returning
Future<String?>
as my future, but my FutureBuilder is expecting a<String?>
. I am usingasync
andawait
to read the data from storage so I expected to returnjwt
as aString
(and it is a string when I print it in the class) but that is apparently not the case when I return it.onTap: () { var jwt = secureStorage.readSecureData('jwt'); print('JWT: $jwt'); },
The above yields:
flutter: JWT: Instance of 'Future<String?>' flutter: KEY: jwt, JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEsInVzZXJuYW1lIjoicmZyZWkiLCJpYXQiOjE2NDk4MjM0NzcsImV4cCI6MTY0OTgyMzU5N30.SiM5sXoqqWtOddLTCsBbdgnNBKSEFVSa8k2gZxg_Fhk
EDIT 4/13/22:
I found a solution. In addition to reading secure storage asynchronously, I also make my call to my secure routing
class
asynchronous like this:onTap: () async { var jwt = await secureStorage.readSecureData('jwt'); var propertyInfo = {'pid': pid, 'propertyName': title}; print(jwt); Navigator.of(context).pushNamed('/devices', arguments: propertyInfo); },
Now I have access to my token. Note that
FutureBuilder
is no longer needed. Removal ofFutureBuilder
, however, also removesBuildContext
which is needed for named routing. To overcome this problem, I pass the buildcontext
fromListView
toListTile
.With access to both of these items, I can finally write the logic I need for gated routing and then use named routing to route the user accordingly.
-
Flutter Secure Storage Platform Exception
I'm using flutter secure storage (^5.0.2) to save tokens but I'm getting the following error when storage.write() is called on an emulator (I'm using Pixel 5 API 30) whereas when I use it on my physical device (Honor 8x) it's working well :
PlatformException (PlatformException(Exception encountered, write, java.lang.NullPointerException: Attempt to invoke interface method 'byte[] com.it_nomads.fluttersecurestorage.ciphers.StorageCipher.encrypt(byte[])' on a null object reference at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.write(FlutterSecureStoragePlugin.java:202) at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.access$300(FlutterSecureStoragePlugin.java:37) at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin$MethodRunner.run(FlutterSecureStoragePlugin.java:289) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.os.HandlerThread.run(HandlerThread.java:67) , null))
Here is the output of the debug :
W/KeyStore( 2975): KeyStore exception W/KeyStore( 2975): android.os.ServiceSpecificException: (code 7) W/KeyStore( 2975): at android.os.Parcel.createExceptionOrNull(Parcel.java:2387) W/KeyStore( 2975): at android.os.Parcel.createException(Parcel.java:2357) W/KeyStore( 2975): at android.os.Parcel.readException(Parcel.java:2340) W/KeyStore( 2975): at android.os.Parcel.readException(Parcel.java:2282) W/KeyStore( 2975): at android.security.keystore.IKeystoreService$Stub$Proxy.get(IKeystoreService.java:988) W/KeyStore( 2975): at android.security.KeyStore.get(KeyStore.java:233) W/KeyStore( 2975): at android.security.KeyStore.get(KeyStore.java:222) W/KeyStore( 2975): at android.security.keystore.AndroidKeyStoreSpi.engineGetCertificate(AndroidKeyStoreSpi.java:165) W/KeyStore( 2975): at java.security.KeyStore.getCertificate(KeyStore.java:1120) W/KeyStore( 2975): at com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.getPublicKey(RSACipher18Implementation.java:90) W/KeyStore( 2975): at com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.wrap(RSACipher18Implementation.java:39) W/KeyStore( 2975): at com.it_nomads.fluttersecurestorage.ciphers.StorageCipher18Implementation.<init>(StorageCipher18Implementation.java:52) W/KeyStore( 2975): at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.ensureInitialized(FlutterSecureStoragePlugin.java:95) W/KeyStore( 2975): at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.access$100(FlutterSecureStoragePlugin.java:37) W/KeyStore( 2975): at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin$MethodRunner.run(FlutterSecureStoragePlugin.java:284) W/KeyStore( 2975): at android.os.Handler.handleCallback(Handler.java:938) W/KeyStore( 2975): at android.os.Handler.dispatchMessage(Handler.java:99) W/KeyStore( 2975): at android.os.Looper.loop(Looper.java:223) W/KeyStore( 2975): at android.os.HandlerThread.run(HandlerThread.java:67) E/FlutterSecureStoragePl( 2975): StorageCipher initialization failed E/FlutterSecureStoragePl( 2975): java.lang.Exception: No certificate found under alias: com.example.applielikya.FlutterSecureStoragePluginKey E/FlutterSecureStoragePl( 2975): at com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.getPublicKey(RSACipher18Implementation.java:92) E/FlutterSecureStoragePl( 2975): at com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.wrap(RSACipher18Implementation.java:39) E/FlutterSecureStoragePl( 2975): at com.it_nomads.fluttersecurestorage.ciphers.StorageCipher18Implementation.<init>(StorageCipher18Implementation.java:52) E/FlutterSecureStoragePl( 2975): at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.ensureInitialized(FlutterSecureStoragePlugin.java:95) E/FlutterSecureStoragePl( 2975): at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.access$100(FlutterSecureStoragePlugin.java:37) E/FlutterSecureStoragePl( 2975): at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin$MethodRunner.run(FlutterSecureStoragePlugin.java:284) E/FlutterSecureStoragePl( 2975): at android.os.Handler.handleCallback(Handler.java:938) E/FlutterSecureStoragePl( 2975): at android.os.Handler.dispatchMessage(Handler.java:99) E/FlutterSecureStoragePl( 2975): at android.os.Looper.loop(Looper.java:223) E/FlutterSecureStoragePl( 2975): at android.os.HandlerThread.run(HandlerThread.java:67)
I don't know if it could be related, but I have min Sdk 19 in my code, due to some packages needing this version.
I need this to start both my physical device and an emulator on Vscode with two different accounts in my app (an admin and an user) to check the transmission of notifications from one to another, if another way to achieve that exists I'd also be up to know.
This is the code :
import 'package:applielikya/models/login_response.dart'; import 'package:applielikya/models/user.dart'; import 'package:applielikya/services/auth/login.dart'; import 'package:applielikya/views/homepage.dart'; import 'package:applielikya/widgets/createRoute.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter/material.dart'; class LoginPage extends StatefulWidget { const LoginPage({Key? key}) : super(key: key); @override State<LoginPage> createState() => LoginPageState(); } enum ButtonState { init, loading, done } class LoginPageState extends State<LoginPage> { final Future<SharedPreferences> _prefs = SharedPreferences.getInstance(); final FlutterSecureStorage storage = const FlutterSecureStorage(); ButtonState _state = ButtonState.init; bool _passwordVisible = false; final TextEditingController _usernameController = TextEditingController(text: "kentay"); final TextEditingController _passwordController = TextEditingController(text: "kentay"); bool _isAuth = false; String _responseMessage = ""; void saveToken(SuccessResponse response) async { await storage.write(key: "accessToken", value: response.accessToken); await storage.write(key: "refreshToken", value: response.refreshToken); } void saveUser(UserResponse user) async { final SharedPreferences prefs = await _prefs; prefs.setString('username', user.username as String); prefs.setInt('id', user.id as int); prefs.setString('role', user.role as String); if (user.role == "prof") { prefs.setString("firstname", user.firstname!); prefs.setString("lastname", user.lastname!); prefs.setString("email", user.email!); } } submitLogin() async { setState(() => _state = ButtonState.loading); final response = await login( UserRequest(username : _usernameController.text, password: _passwordController.text) ); setState(() { _isAuth = response.auth; _state = ButtonState.done; }); if (response is SuccessResponse) { saveToken(response); saveUser(response.user); setState(() => _state = ButtonState.init); Navigator.of(context).push( createRoute( const MyHomePage(), const Offset(0.0, 1.0), Offset.zero, Curves.easeInCirc ) ); } else { if (response is ErrorResponse) { setState(() => _responseMessage = response.message); } } }
-
Flutter check if app was uninstall or first time
I have a flutter app and I use flutter secure storage. I am implementing FCM ( Firebase Cloud Messaging ) push notifications in the application.
I have a main screen where, after the user logged in I, check if the user is using the app for the first time or if the app was uninstalled.
I do this check by a key from secure storage, if the value of the key is null then I assume that the user is using for the first time the app. So if it is for the first time I insert in the databse the token received from firebase.
The question: Is this approach valid for the case when the app was uninstalled or the storage cleared? Normally if the user uninstalled the application and after a while he install the app again the storage should be cleared and that key should be null, right?
Thank you!