我一直在摸索不同的实现和想法,以使这个工作,但我觉得我不是干这样做或尽可能聪明。我一直在关注这个"教程" Angular Auth
所以,我有一个功能齐全的laravel(4.2)后端设置,其中一些资源路由受到oauth过滤器的保护。我正在使用密码授予,一切都在那里工作得很好。我已经设置了登录/退出路线,并且能够登录到我的Ionic应用程序并从laravel获取和access_token和refresh_token就好了。使用refesh_token获取新的access_tokens也可以正常工作。但是,我在尝试弄清楚如何正确处理Ionic中的以下事情时遇到了一些问题:
我尝试过什么
在我之前提到的文章中,他在run模块中设置了一个rootScope观察器,它监视statechangestart事件。
$rootScope.$on('$stateChangeStart', function (event, next) {
var authorizedRoles = next.data.authorizedRoles;
if (!AuthService.isAuthorized(authorizedRoles)) {
event.preventDefault();
if (AuthService.isAuthenticated()) {
// user is not allowed
$rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
} else {
// user is not logged in
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
}
});
我没有使用角色所以当我实现这个时,我就有了类似的东西
$rootScope.$on('$stateChangeStart', function(event, next) {
if (next.url != "/login") {
AuthService.isAuthenticated().then(function() {
console.log('you are already authed an logged in and trying to access: ' + next.url);
}, function() {
event.preventDefault();
console.log('YOU DO NOT HAVE A VALID ACCESS TOKEN');
$location.path('/app/login');
});
}
});
isAuthenticated()只是在我的oauth过滤器中命中一条路径,所以如果它抛出一个错误(例如401),我知道access_token是坏的。然后我在我的AuthService服务中有一个私有方法,试图使用存储的用户刷新一个新的access_token
function useRefreshToken() {
console.log('Using refresh token to get new token:');
var deferred = $q.defer();
$http({
method: 'POST',
url: base_url.dev.url + 'oauth/access_token',
data: $.param({
grant_type: 'refresh_token',
client_id: API.client_id,
client_secret: API.client_secret,
refresh_token: $localStorage.session.refresh_token
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function(data) {
console.log('refresh token worked!');
$localStorage.session.access_token = data.access_token;
$localStorage.session.refresh_token = data.refresh_token;
deferred.resolve();
}).error(function(error) {
console.log('refresh token failed');
CurrentUserService.setLogged(false);
console.log(JSON.stringify(error));
deferred.reject(error);
});
return deferred.promise;
};
如果上面的方法返回一个被拒绝的承诺,我只是假设(这可能是个好主意?)刷新令牌已经过期,因此用户需要重新登录并检索新的访问权限。从我的laravel oauth / access_token路由刷新令牌对。
所以上面的方法一直很好,因为我能够检查用户access_token是否有效,如果没有使用用户refresh_token检索新的access_token。
这是我的isAuthenticated方法,以防你想看到它。它是我的AuthService服务中的公共方法。
isAuthenticated: function() {
console.log('Checking if token is still valid.');
var deferred = $q.defer();
$http.get(base_url.dev.url + 'valid-token', {
params: {
access_token: $localStorage.session.access_token
}
}).success(function(data) {
console.log('Token is still valid.');
CurrentUserService.setLogged(true);
deferred.resolve();
}).error(function(error) {
console.log(JSON.stringify(error));
useRefreshToken().then(function() {
deferred.resolve();
}, function(error) {
deferred.reject(error);
});
});
return deferred.promise;
}
我遇到的一个大问题是,因为AuthService.isAuthenticated()方法运行异步,所以应用程序更改为的状态(例如PHOTOS)将在isAuthenticated返回之前被触发,如果我们在之前提到了Case:1在我的帖子的开头,PHOTOS状态将尝试使用无效的access_token在isAuthenticated方法能够使用refresh_token获取新的access_token之前尝试使用我的后端资源。
现在我可以通过在每个状态上使用解析来避免上述问题,该状态使用isAuthenticated方法检查access_token并在需要消耗资源时获取新的状态。但那感觉非常糟糕。我为这篇文章的篇幅道歉,但我想确保你们知道所发生的一切以及我想要完成的事情。
感谢任何反馈,批评和指导!谢谢你们。