This Widget opens a new Fullscreen Window on top of your current app and takes you to your custom auth url. The Widgets WebView listens for the code
response to handle the 2 leg-auth and then also listens for your redirect_url
and upon that load saves your token (if configured) and then executes the onSuccess function where you can control (and close) the Widget.
var adalWidget = Alloy.createWidget('ti.oauth2');
adalWidget.customServer = true;
adalWidget.customAuthUrl = 'https://yoururl.com/connect/authorize';
adalWidget.customTokenUrl = 'https://yoururl.com/connect/token';
adalWidget.customLogoutUrl = 'https://yoururl.com/connect/session/logout';
adalWidget.customCookieUrl = 'https://yoururl.com/';
adalWidget.clientId = 'clientidhere';
adalWidget.clientSecret = 'secret-guid-would-go-here';
adalWidget.scope = 'scope-one scope-two';
adalWidget.redirectUrl = 'https://redirecturl.com';
adalWidget.responseType = 'code';
adalWidget.grantType = 'authorization_code';
adalWidget.customTitleText = 'My App Login Title';
adalWidget.saveTokensToTiProperties = true; //saves to Ti.App.Properties.getString ('azure-ad-access-token');
//prompt/show UI | success CB | error CB | allowCancel | cancel CB
adalWidget.authorize(true, onSuccess, onError, true, onCancel);
function onSuccess(authResults) {
adalWidget.close();
}
Open Login Window with the assigned properties (see below)
Close Login Window
true
- use your own server (be sure to also definecustomAuthUrl
&customTokenUrl
)
false
- use MS Graph/Azure AD
URL to use for the initial Auth request
URL to use for the (2nd leg) Token request
Tenant GUID or Domain
GUID provided by your server
GUID provided by your server
List of scopes to authorize. Each seperated by a space
URL configured in your server
code
(default)
authorization_code
(default)
Text to use in the TitleBar of the iOS/Android App
true
- saves the token to Ti Properties so that it is accessible throughout the app and available after restarts
Show UI
Function used in callback for successful authenitcation
Function used in callback for unsuccessful authentication
Determines whether to allow the use of Cancel during authentication
Function executed, if (allowCancel === true) && user clicks to execute
In my use case, my Identity Server expires my tokens after a period of time. I wanted to capture when my refresh token was going to expire and upon resuming my app, if the expiration time was in the next 10 minutes, I wanted to go ahead and renew the token before the user got into using the app.
To accomplish that, in my onSuccess
function I did the following:
function onSuccess(authResults) {
var secondsToSetExpiration = parseInt(authResults.expires_in) - 600; //subtract 10 minutes
var expDate = moment().add(secondsToSetExpiration, 'seconds'); //find that timestamp
Ti.App.Properties.setString('azure-ad-access-token-exp', expDate); //set the time stamp for future reference
}
Then in my resume
event I check the current time against the expiration time (less 10 minutes)
Ti.App.addEventListener('resumed', function (e) {
Ti.API.info('APP RESUMED');
var tokenExp = moment(Ti.App.Properties.getString('azure-ad-access-token-exp')).format();
var currentExp = moment().format();
if (currentExp > tokenExp) {
adalWidget.authorize(false, onRefreshSuccess, onRefreshError, true, onRefreshCancel);
} //else no refresh needed, more than 10 minnutes before expiring
});
Take Note: that my first parameter is set to
false
. This keeps the Auth refresh window "in the background". Also, I have slightly differentonSuccess
andonError
functions to handle this scenario. Your results may vary.
I chose to have this Widget pop over the top of my app so that I can inject and use from within anywhere in my app. That also means I have my own "login" screen where I have a button that I use to allow for manual authentication (in cases where network services fail) as well as provide feedback/status to the user ("Authenticating...", "Opening App...",) and on failure back to "Login".
In my RESTe API Endpoint definitions I added a check for any 401
errors and then execute launching the Widget to re-Auth
...
onError: function(e, retry){
if (e.code === 401) {
Alloy.PersistentEvents.trigger('app:unauthorizedRequest');
} else {
//handle other errors here
}
}
...