cakephp - Using Access Tokens with JavaScript in OAuth2 -


this i've tried information on i've never found actual answer or solution problem. can clarify , point me in right direction.

i've split problems 3 questions @ bottom, if answered 1,2,3 that'd make things easier digest , me head around this.

so basically, have oauth2 sever setup using cakephp following javascript can communicate allow user login , access token , make various requests different endpoints using token send , receive data.

var access_token,      refresh_token;  var app = {     init: function() {         $(document).ready(function(){             users.checkauthenticated();         });     }(),     splash: function() {         var contentlogin = '<input id="username" type="text"> <input id="password" type="password"> <button id="login">log in</button>';         $('#app').html(contentlogin);     },     home: function() {           var contenthome = '<h1>welcome</h1> <a id="logout">log out</a>';         $('#app').html(contenthome);     } };  var users = {     init: function(){         $(document).ready(function() {             $('#login').live('click', function(e){                 e.preventdefault();                 users.login();             });              $('#logout').live('click', function(e){                 e.preventdefault();                 users.logout();             });         });     }(),      // check if user logged in (has access token)      checkauthenticated: function() {         access_token = window.localstorage.getitem('access_token');         if( access_token == null ) {             users.logout();         }         else {             users.checktokenvalid(access_token);         }     },      // check token still valid on server access (also user info)      checktokenvalid: function(access_token){          $.ajax({             type: 'get',             url: 'http://domain.com/api/oauth/userinfo',             data: {                 access_token: access_token             },             datatype: 'json',             success: function(data) {                  console.log('success');                  console.log(data);                  if( data.error ) {                     refresh_token = window.localstorage.getitem('refresh_token');                      if( refresh_token == null ) {                          users.logout();                      } else {                          users.refreshtoken(refresh_token);                     }                 } else {                     app.home();                 }             },             error: function(a,b,c) {                  console.log('error');                  console.log(a);                  refresh_token = window.localstorage.getitem('refresh_token');                 if( refresh_token == null ) {                      users.logout();                  } else {                      users.refreshtoken(refresh_token);                 }             }         });      },      // request new access token using refresh token      refreshtoken: function(refresh_token){          $.ajax({             type: 'get',             url: 'http://domain.com/api/oauth/token',             data: {                 grant_type: 'refresh_token',                 refresh_token: refresh_token,                 client_id: 'ntezn2fjnzzlyzu4zgm2'             },             datatype: 'json',             success: function(data) {                 if( data.error ) {                     alert(data.error);                 } else {                     window.localstorage.setitem('access_token', data.access_token);                     window.localstorage.setitem('refresh_token', data.refresh_token);                     access_token = window.localstorage.getitem('access_token');                     refresh_token = window.localstorage.getitem('refresh_token');                     app.home();                 }             },             error: function(a,b,c) {                 console.log(a,b,c);                 users.logout();             }         });      },      // send login credentials , store tokens in localstorage , in variables      login: function() {         $.ajax({             type: 'get',             url: 'http://domain.com/api/oauth/token',             data: {                 grant_type: 'password',                 username: $('#username').val(),                 password: $('#password').val(),                 client_id: 'ntezn2fjnzzlyzu4zgm2'             },             datatype: 'json',             success: function(data) {                 if( data.error ) {                     alert(data.error);                 } else {                     window.localstorage.setitem('access_token', data.access_token);                     window.localstorage.setitem('refresh_token', data.refresh_token);                     access_token = window.localstorage.getitem('access_token');                     refresh_token = window.localstorage.getitem('refresh_token');                     app.home();                 }             },             error: function(a,b,c) {                 console.log(a,b,c);             }         });     },      // clear localstorage , token variables , load login (splash page)      logout: function() {         localstorage.removeitem('access_token');         localstorage.removeitem('refresh_token');         access_token = window.localstorage.getitem('access_token');         refresh_token = window.localstorage.getitem('refresh_token');         app.splash();     } }; 

hopefully code makes sense... in nutshell, sends username , password api sends both access_token , refresh_token store using localstorage in html5. refresh_token used new access_token once access_token no longer works user gets seamless experience without having keep logging in (unless log out!). handled checktokenvalid function call check it's still valid, , either request new token or make user log in again if refresh_token doesn't exist (or invalid).

  1. the first problem having store refresh_token. not issue it'd stored server-side, because it's client side client id exposed , therefore if access users browser, request new tokens. how keep user logged in (i.e. request new access_token automatically) without using refresh tokens? is issue it's on users machine!

  2. the second problem, i've been told shouldn't using type of grant type (password/resource owner password credentials), because it's client-side , therefore things client id, , secret can't protected. , should instead, using implicit. i've not been able see how me solve first problem. can show example of this? , how solve refresh_token issue above. have read regarding implicit grant type, it's doing simplifying token process (by removing need client id) , doesn't different.

  3. finally, because application application using api, there no need user ever go via token grant type process, whole setting of client ids seems overkill javascript talking api. other options have? i've thought sacking off oauth , going basic auth instead... sessions? won't have token then! thoughts?

1. how keep users having log in on every request

nobody forces issue refresh tokens, or expire access tokens on every request. if issue access token valid hour or two, should enough time user use website without allowing sort of "endless" refresh chain refresh tokens offer (as typically using refresh token result in both new access , refresh token being issued). choose expiration period allow typical user action period, allow extra, , can avoid issuing refresh tokens altogether.

of course, there risk user exceed time span , forced log in again. think if happens, if explained them happens security reasons , happened in easy, non-technical terms, okay that. in end, it's trade-off between best security , best usability: better usability using refresh tokens, - users never forced re-login while they're using page - if do, have live there being risk of them becoming compromised.

local storage protected same origin policy, it's secure browser has offer storing things. personally, idea of using session cookie storing tokens - works across browser tabs, gets cleared when browser closed , when user manually clears cookies, expected behavior of being "forgotten" page (which won't browser local/session storage). if this, make sure use secure cookie. setting cookie path non-existent value keep being transmitted on every request, although purely message size consideration, transmitted on every request anyways (in authorization header). whatever storage type use, susceptible xss attacks, make sure guard against it.

my point in nutshell: you're not required issue refresh tokens or expire access tokens on every request. if want avoid using refresh tokens, make access tokens live longer - you'll have live there being chance users have re-authenticate while using website.

2. use of implicit flow on resource owner password credentials flow

the reason you're discouraged using resource owner password credentials flow because forces user expose credentials for identity provider you're using authenticate them. i.e. if you're allowing users sign in using google/facebook, shouldn't use flow because user have give username , password app/website, , kinds of shenanigans them.

since on other hand, how understand question, have your own oauth2 server , running, you're own identity provider - have access user's credentials (user name , hashed password), avoiding resource owner flow has no additional security benefits. rfc 6749 not specify client id , secret used flow (and not make sense, either), hence, no need protect don't have supply.

my point in nutshell: because own identity provider using resource owner password credentials flow okay. don't need client id and/or secret this. autorization grant flow , implicit flow meant when authenticate against different identity provider (such google or facebook)

3. keep or not keep token based authentication

the commonly used authentication mechanism still session based, i.e. server, when have logged in, issues session id keeps track of fact you've authenticated. typically session id gets stored cookie. beauty have pretty no implementation concerns - set cookie, , browser handle pretty nitty gritty details you. on server, have check session valid. however, mechanism still susceptible xss attacks, and, worse, xsrf (cross-site request forgery). while not impossible guard against, bit of pain detect , prevent happening. token based authentication system, xsrf protection built-in.

my point in nutshell: since have oauth2 server , running, stick it. if go resource owner password credentials flow, there no need client id , secret used.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -