Hello @ALL
I already posted this question on Qt Maps SDK Questions community and get redirected to AppStudio Community
My mobile app session under IOS doesn't persist after closing : the user needs to login every time to use the application
For my Android version, the user needs to login the first time only, then the session still available for the next times
Technique environment :
AppStudio : 5.1.80
QT : 5.15.2
ArcGIS Runtime SDK for QT : 100.11.2.3121
Does anyone have an idea about this issue
Solved! Go to Solution.
Here's the core of the code I'm using. Assuming you have all the properties defined etc. You'll also need an AuthenticationView defined in scope somewhere too.
// assuming you have a AuthenticationView defined
// for signing into a portal instance
AuthenticationView {
id: authView
anchors.fill: parent
}
// this goes in your main app component
Component.onCompleted: {
// we are using secure storage to store a refresh token that is attempted to be retrieved
// if the secureStorage.getContent("appRefreshToken") returns an empty string
// i.e. the refresh token has never been stored
// then don't pass it into the credential which will prompt for sign in (using the authView defined above)
// if the refresh token is successfully retrieved from storage pass it into the credential which will use it to generate a fresh token
// create oAuth info specifying that we are requiring a named user sign in and a clientid unique to this app
let oAuthClientInfo = ArcGISRuntimeEnvironment.createObject("OAuthClientInfo", {
oAuthMode: Enums.OAuthModeUser,
clientId: app.clientId
});
let credential = ArcGISRuntimeEnvironment.createObject("Credential", { oAuthClientInfo: oAuthClientInfo });
// attempt to get the refresh token from storage
// so it can be used to generate an access token rather than forcing user to log in again
const refreshToken = secureStorage.getContent("appRefreshToken");
// if we got a refresh token apply it to the credential
// if we did not get one, returns empty string if the key is not found in storage
// don't set the credential refresh token which will prompt for sign in via AuthenticationView
// when loading the portal
if(refreshToken !== "") {
credential.oAuthRefreshToken = refreshToken;
credential.tokenServiceUrl = "%1/sharing/rest/oauth2/token".arg(app.portalUrl);
}
app.portal = ArcGISRuntimeEnvironment.createObject("Portal", {url: app.portalUrl, credential: credential});
app.portal.load();
app.portal.onLoadStatusChanged.connect(()=>{
if (app.portal.loadStatus === Enums.LoadStatusFailedToLoad) {
console.log(app.portal.error.message);
// assume our refresh token was invalidated so set to empty which prompts for log in
app.portal.credential.oAuthRefreshToken = "";
app.portal.retryLoad();
}
else if(app.portal.loadStatus === Enums.LoadStatusLoaded) {
// store the refresh token and token service url for retrieval next time the app is started
// so the user isn't prompted to log in again
secureStorage.setContent("appRefreshToken", app.portal.credential.oAuthRefreshToken);
secureStorage.setContent("tokenServiceUrl", app.portal.credential.tokenServiceUrl);
}
})
}
Good Luck! :collision:
You'll want to store the refresh token that you get back along with the access token when logging in initially. You can then retrieve that refresh token and use it to generate an access token each time the app is fired up. You'd only then be prompted for login when that refresh token expires. I think the default is 2 weeks (?). I pulled a solution together from a couple samples using SecureStorage. Sorry but I can't find the samples I used at the moment. I can drop a few lines of code here to help get you started if that would be helpful.
Hello @DavidPuckett
Thank you for your appreciated reply.
Yes please. I would like to see how you implemented this methode.
Thanks again
Regards
Here's the core of the code I'm using. Assuming you have all the properties defined etc. You'll also need an AuthenticationView defined in scope somewhere too.
// assuming you have a AuthenticationView defined
// for signing into a portal instance
AuthenticationView {
id: authView
anchors.fill: parent
}
// this goes in your main app component
Component.onCompleted: {
// we are using secure storage to store a refresh token that is attempted to be retrieved
// if the secureStorage.getContent("appRefreshToken") returns an empty string
// i.e. the refresh token has never been stored
// then don't pass it into the credential which will prompt for sign in (using the authView defined above)
// if the refresh token is successfully retrieved from storage pass it into the credential which will use it to generate a fresh token
// create oAuth info specifying that we are requiring a named user sign in and a clientid unique to this app
let oAuthClientInfo = ArcGISRuntimeEnvironment.createObject("OAuthClientInfo", {
oAuthMode: Enums.OAuthModeUser,
clientId: app.clientId
});
let credential = ArcGISRuntimeEnvironment.createObject("Credential", { oAuthClientInfo: oAuthClientInfo });
// attempt to get the refresh token from storage
// so it can be used to generate an access token rather than forcing user to log in again
const refreshToken = secureStorage.getContent("appRefreshToken");
// if we got a refresh token apply it to the credential
// if we did not get one, returns empty string if the key is not found in storage
// don't set the credential refresh token which will prompt for sign in via AuthenticationView
// when loading the portal
if(refreshToken !== "") {
credential.oAuthRefreshToken = refreshToken;
credential.tokenServiceUrl = "%1/sharing/rest/oauth2/token".arg(app.portalUrl);
}
app.portal = ArcGISRuntimeEnvironment.createObject("Portal", {url: app.portalUrl, credential: credential});
app.portal.load();
app.portal.onLoadStatusChanged.connect(()=>{
if (app.portal.loadStatus === Enums.LoadStatusFailedToLoad) {
console.log(app.portal.error.message);
// assume our refresh token was invalidated so set to empty which prompts for log in
app.portal.credential.oAuthRefreshToken = "";
app.portal.retryLoad();
}
else if(app.portal.loadStatus === Enums.LoadStatusLoaded) {
// store the refresh token and token service url for retrieval next time the app is started
// so the user isn't prompted to log in again
secureStorage.setContent("appRefreshToken", app.portal.credential.oAuthRefreshToken);
secureStorage.setContent("tokenServiceUrl", app.portal.credential.tokenServiceUrl);
}
})
}
Good Luck! :collision:
Hello @DavidPuckett
Thank your for your code. I appreciate !
I added this to my code and still testing. It sounds workign until now.
Regards