1

I have an issue with using mobile app that I created in Ionic and back-end APIs that I coded in play framework, my issue simply is I need way to handle security matter for calling APIs that need to be secured, mean user must be logged in to do actions, as example guest can view group but can join only if logged in.

My issue that I believe that cookies is not supported for Mobile, i have code checking session that stored in cookies, its working for website, but it will not work for mobile, right?

Currently I'm trying to send a token that generated in back-end and returned with login response and stored in localStorage in Ionic, but my issue is that I can't sent token to be validated with request.

Front End: I have the following http interceptor :

  angular
    .module('app.core')
    .factory('sessionInjector', sessionInjector);

  /** @ngInject */
  function sessionInjector($q, sessionService, $rootScope) {
    return {
      request: function (config) {
        $rootScope.$broadcast('loading:show');
        if (!sessionService.isAnonymous())
          config.headers['x-session-token'] = sessionService.getToken();
        }
        return config;
      }
  }

Back-End: Controller:

    @Security.Authenticated(Secure.class)
    public Result joinOrganization() {

       // Do some business

    }

Secure.java :

@Override
public String getUsername(Http.Context ctx) {
    // Is this correct way? I get null here
    String str = ctx.request().getHeader("x-session-token");

    String userId = ctx.session().get("usedId");

    if (userId == null) {
        return null;
    }

    User user = Play.application().injector().instanceOf(UserService.class).findUserById(Integer.parseInt(userId));

    if (user != null && user.isActive) {
        return user.id;
    } else {
        return null;
    }
}


@Override
public Result onUnauthorized(Http.Context ctx) {
    return unauthorized(results);
}

Note: Tokens stored in database:

Entity:

@Entity
@Table(name = "AUTHTOKEN")
public class AuthToken extends BaseModel {

    @OneToOne(targetEntity = User.class, cascade = CascadeType.REFRESH, optional = false)
    public User user;

    @Column(nullable = false)
    public String token;

    @Column
    public long expiration;

    public AuthToken() {
    }

}

For cookies working, but need to remove cookies and use tokens, or use them together cookies for website, tokens for mobile .

Al-Mothafar
  • 7,949
  • 7
  • 68
  • 102

2 Answers2

0

Mobile is no different to otherwise in regards of cookies. There are restrictions if AJAX, or cross-domain requests are used, and specially with Apple stuff, but they apply to non-mobile too. If your cookies work on a PC/Mac, they should do on a mobile device just as well. It's more of a form factor than anything else...

ptrk
  • 1,800
  • 1
  • 15
  • 24
  • No mobile "apps" not accept cookies, and cookies not working, the web browser is different than a native app. – Al-Mothafar Apr 19 '16 at 14:13
  • Mobile browser _is_ a native app. If a native app is using HTTP and does not support cookies, then it's specific to the app, not a rule in general. If it's communicating with a server that relies on the cookies to support sessions, then the application is poorly written I guess... – ptrk Apr 19 '16 at 14:18
  • the browser has his own functions and APIs, can you add cookies to photoshop ! or can you draw and modify images inside notepad ? and what if you blocked cookies as a user? cookies is a part of browsers not for a native apps. – Al-Mothafar Apr 19 '16 at 14:28
  • Also HTTP could be with or without cookies, and at the last, i'm working on the app that I tested, the cookies not working in Android or iOS apps, but working only in browsers when I was working with cookies. – Al-Mothafar Apr 19 '16 at 14:31
  • That's my last comment here: cookies are working regardless of mobile or desktop. They are described here https://tools.ietf.org/html/rfc6265 and there's no distinction to the device type. Ionic and Angular play along as well: http://blog.ionic.io/angularjs-authentication/ – ptrk Apr 19 '16 at 16:24
  • links you provided to me talking about "browsers" ! and my last reply, I'm talking about what I have tried, I simply use so basic calls that was working in web, to set cookies and get them, but was not working, and still not working, i'm setting test value here that I get and retrieve from wbe, but not from mobile apk installed, while debug in backend ! – Al-Mothafar Apr 20 '16 at 08:08
0

I found solution and it was complicated because there are many issues starting from that ngResource does not apply request interceptor its an issue opened from long time.

Second issue was how to send the token with ngResource, its simply with adding headers, the another issue here is getting dynamically the token, this "dynamically" means because the localStorage in memory getting lost when refresh so you need to get back it, this can be done with service, and function call for getting the token, something like this :

$resource('/user/:userId/card/:cardId', {userId:123, cardId:'@id'}, {
  charge: {method:'POST', params:{charge:true}, headers = {
        'x-session-token': function () {
          return sessionService.getToken()
        }}
 });

Inside sessionService :

// this to recreate the cache in memory once the user refresh, it will keep the data if exisit but will point to it again in memory 
if (CacheFactory.get('profileCache') == undefined) {
  //if there is no cache already then create new one and assign it to profileCache
  CacheFactory.createCache('profileCache');
}

function getCurrentSession() {
  var profileCache = CacheFactory.get('profileCache');
  if (profileCache !== undefined && profileCache.get('Token') !== undefined) {
    return profileCache.get('Token');
  }
  return null;
}

function getToken() {
  var currentSession = getCurrentSession();
  if (currentSession != null && currentSession != '') {
    return currentSession.token;
  }
  return null;
}

And then this method will work inside Secure.java

protected User getUser(Http.Context ctx) {
    String token = ctx.request().getHeader("x-session-token");  

    if (token != null) {
        return securityService.validateToken(token);
    }
    return null;
}
Al-Mothafar
  • 7,949
  • 7
  • 68
  • 102