Skip to content

adamtarmstrong/ti.oauth2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ti.oauth2

Ti Alloy Widget for oAuth2

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.


Rating.  Feedback

Usage

Create Instance

var adalWidget = Alloy.createWidget('ti.oauth2');

Define parameters

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');

Launch Login

//prompt/show UI   |   success CB  |   error CB    |   allowCancel  |   cancel CB
adalWidget.authorize(true, onSuccess, onError, true, onCancel);

Success Function

function onSuccess(authResults) {
	adalWidget.close();
}



Methods

authorize

Open Login Window with the assigned properties (see below)


close

Close Login Window



Properties configured up front

customServer {BOOL}

true - use your own server (be sure to also define customAuthUrl & customTokenUrl)
false - use MS Graph/Azure AD


customAuthUrl {String}

URL to use for the initial Auth request


customTokenUrl {String}

URL to use for the (2nd leg) Token request


tenant {String)

Tenant GUID or Domain


clientId {String}

GUID provided by your server


clientSecret {String}

GUID provided by your server


scope {String}

List of scopes to authorize. Each seperated by a space


redirectUrl {String}

URL configured in your server


responseType {String}

code (default)


grantType {String}

authorization_code (default)


customTitleText {String}

Text to use in the TitleBar of the iOS/Android App


saveTokensToTiProperties {BOOL}

true - saves the token to Ti Properties so that it is accessible throughout the app and available after restarts



Properties passed in w/ .authorize() Method

prompt {BOOL}

Show UI


onSuccess {Function}

Function used in callback for successful authenitcation


onError {Function}

Function used in callback for unsuccessful authentication


allowCancel {BOOL}

Determines whether to allow the use of Cancel during authentication


onCancel {Function}

Function executed, if (allowCancel === true) && user clicks to execute



Extra

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 different onSuccess and onError 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
    }
}
...

About

Ti Alloy Widget for oAuth2

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published