Play framework and ionic for mobile 我需要 Security without cookies 但 token

Play framework and ionic for mobile I need Security without cookies but token

我在使用在 Ionic 中创建的移动应用程序和在 play 框架中编码的后端 API 时遇到问题,我的问题只是我需要一种方法来处理调用需要保护的 API 的安全问题,意味着用户必须登录才能执行操作,例如来宾可以查看组但只有在登录后才能加入。

我的问题是移动设备不支持 cookie,我有存储在 cookie 中的代码检查会话,它适用于网站,但不适用于移动设备,对吗?

目前我正在尝试发送一个令牌,该令牌在后端生成并随登录响应返回并存储在 Ionic 的 localStorage 中,但我的问题是我无法发送令牌以通过请求进行验证。

前端: 我有以下 http 拦截器:

  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;
      }
  }

后端: 控制器:

    @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);
}

注意:数据库中存储的令牌:

实体:

@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() {
    }

}

对于 cookie 工作,但需要删除 cookie 并使用令牌,或者将它们一起用于网站 cookie,移动令牌。

在 cookie 方面,移动设备与其他设备没有什么不同。如果使用 AJAX 或跨域请求会有限制,特别是对于 Apple 的东西,但它们也适用于非移动设备。如果您的 cookie 在 PC/Mac 上工作,它们在移动设备上也应该能正常工作。它比其他任何东西都更重要...

我找到了解决方案,但它很复杂,因为从那开始有很多问题 ngResource does not apply request interceptor 这是一个很久以前就打开的问题。

第二个问题是如何使用 ngResource 发送令牌,只需添加 headers,这里的另一个问题是动态获取令牌,这个 "dynamically" 意味着因为 localStorage 刷​​新时内存丢失,所以你需要取回它,这可以通过服务和获取令牌的函数调用来完成,如下所示:

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

会话服务内部

// 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;
}

然后这个方法将在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;
}