1

I just built a simple application calling a rest api built with symfony and secured with fos_oauth.

I have a AuthService that return an access token that allow my mobile application to access to my api.

It is stored in local storage :

Local storage

On my browser using ionic serve (similar to phonegap serve) the application is perfectly working and i can access to my variable stored locally. When emulating with ios, it is perfectly working. But when emulating with android or displaying my app on my phone with phonegap app. I can't access to those variables. Does that sound normal to you?

[phonegap] 404 http://ynd.dev/api/login?access_token=undefined

Android vs Ios

index.html :

<!-- Utils -->
<script src="js/service/LocalStorageService.js"></script>

<!-- JS Config -->
<script src="js/functions.js"></script>
<script src="js/config/parameters.js"></script>

<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/config/routing.js"></script>
<script src="js/service/AuthService.js"></script>

LocalStorageService.js :

setObject: function(key, value) {
    $window.localStorage.setItem(key, JSON.stringify(value));
},
getObject: function(key) {
    return JSON.parse($window.localStorage.getItem(key) || '{}');
}

parameters.js :

// Resources
var domain = 'http://ynd.dev';
var public_id = '4_4spkzm1pubcw40og04okk4wogs0cc44wkgkkoco88k8cwgkwgs';
var secret = '28es09ymlcg0wgskgs4cso0co0ok0ww0gw8g0k8g4kcowckcco';

// Access token
var access_token = '';
var identity_token = '';

app.js :

var app = angular.module('ionicApp', ['ionic', 'ionic.utils', 'ngResource']);

app.run(function($ionicPlatform,$rootScope, $localStorage, $location, AuthService) {

  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }

    access_token = $localStorage.getObject('access_token');
    identity_token = $localStorage.getObject('identity_token');

    AuthService.token();

  });
  $rootScope.$on('$stateChangeStart', function (event, next) {

    access_token = $localStorage.getObject('access_token');
    identity_token = $localStorage.getObject('identity_token');

    AuthService.token();

    // IF no user logged
    if(isObjectEmpty(identity_token)){

      $location.path( "/login" );

    }

  });
});

AuthService:

This is how the object is stored in local.

$localStorage.setObject('access_token', {
                            key: res.data.access_token,
                            type: 'anonymous',
                            expires_at: Date.now()+(res.data.expires_in*1000)
                        });

Any ideas or hints?

UPDATE : (CORS)

allow_origin: ['*'] 
allow_headers: ['*'] 
allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
Brieuc
  • 3,994
  • 9
  • 37
  • 70
  • 1
    You should try to log localstorage on your setObject/getObject, to give more info. I don't see obvious reason, but you should use localStorage.getItem(key) and .setItem(key) instead of localStorage[key], it's better http://stackoverflow.com/questions/12632463/is-localstorage-getitemitem-better-than-localstorage-item-or-localstoragei note that I don't see how that could resolve your problem, that's just an optimization. – Boris Charpentier Mar 09 '15 at 09:05
  • Where does the alert field actually come from? Where exactly in your code do you call the alert? – Rias Mar 09 '15 at 11:30
  • I just put an alert in my login service before i call the url 'http://ynd.dev/api/login?access_token='+access_token – Brieuc Mar 09 '15 at 13:02

2 Answers2

0

When using the app within Phonegap the application is called from the file system, thus runs on the file:// protocol. When you wan to call your server, you will need to use JSONP or CORS headers on your server to make a successful connection, as otherwise cross-domain security policies will arise.

Rias
  • 1,956
  • 22
  • 33
  • The server side is using Symfony2 with FOS Rest bundle and Nelmio Cors Bundle. The settings are already done and working. My application is actually already outside my server side and the application is correctly getting the data from it. Only on phonegap App and Android emulated i can't access to the local stored variables (or the stored variable didn't get the data from the server). Here the cors setting updated in the post. – Brieuc Mar 09 '15 at 11:05
  • does the problem exist in real android devices too or in iOS emulater e.g.? – Rias Mar 09 '15 at 11:20
  • IOS emulator is working great an returning the right value. Android emulator is returning undefined. Phonegapp App that allow to test it via IP on Iphone or Android phone (without compiling) is also returning undefined. – Brieuc Mar 09 '15 at 11:23
  • 1
    I'm not familiar with Phonegap "via IP without compiling", but maybe your emulator doesn't support localStorage and Phonegap via IP has some kind of domain mismatch. Did you try and compile the app and let it run on the devices? – Rias Mar 09 '15 at 11:29
  • Not yet, that something i could try. not sure how to do it yet. i'm new with that. It is possible that indeed there is no support for localStorage, that is at least the best guess i had too. – Brieuc Mar 09 '15 at 11:31
  • 1
    Well emulators are just emulators, and in some cases they behave differently. From what I see in your code it's looks correct to me and with the correct CORS headers it should at least retrieve and store the value to localStorage within most browsers and devices. So in your case i would try and make sure first, that the problem is not the emulators :) – Rias Mar 09 '15 at 11:35
  • Thank you for the hint, i'll make sure about that. – Brieuc Mar 09 '15 at 13:01
0

It was simply not working because the emulated application does not access the localhost.

First solution :

Call the api from an online host.

Second solution :

Instead of calling http://localhost/ Call the IP (You can get it with a ifconfig, for myself i used ifconfig vboxnet0).

For vitual host i have not figure it out.

Brieuc
  • 3,994
  • 9
  • 37
  • 70