[英]Restrict operations in restful PHP API
我正在創建一個用PHP編寫的Restful API作為后端的AngularJS應用程序。 這是我第一次“一起”使用AngularJS和PHP。
Angular正在使用ngCookies模塊跟蹤用戶身份驗證。 某些操作(例如刪除內容)僅應提供給具有特定特權的用戶。 如何確保“正常”用戶或未登錄的用戶無法訪問API的刪除操作?
任何想法表示贊賞。
這是我的方法。
users
數據庫表中,我添加名為token VARCHAR(36)
lastlogin
專欄 MD5($ip.$email.$logindate)
更新該令牌 在Angular $http
服務中,我添加了攔截器,並在進行任何請求之前設置了Authentication
標頭。 我使用基本身份驗證。 我創建了字符串$user_id.'::'.$token
。
app.factory('authInterceptor', function($rootScope, $q, appConfig, $injector, $cacheFactory) { function request(config) { if(angular.isDefined($rootScope.currentUser.id)) { config.headers.Authorization = 'Basic ' + window.btoa($rootScope.currentUser.id + ':' + $rootScope.currentUser.token); } return config; } function response(response) { if(angular.isDefined(response.data.code) && parseInt(response.data.code) == 401) { var UserApi = $injector.get('UserApi'); UserApi.logout(); $cacheFactory.get('$http').removeAll(); UserApi.login(response.data.message) .catch(function() { var $state = $injector.get('$state'); $state.go('app.home'); }); } return response || $q.when(response); } return { request: request, response: response }; })
這是我插入到應用程序中的authInterceptor
工廠
app.config(function($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
})
如果用戶被授權,那么我會為每個請求設置標准的Authentication
標頭。
然后在PHP中,我得到了這個頭文件。 我分別獲得用戶ID和令牌。 然后,我使用用戶ID從具有令牌和上次登錄日期的數據庫中獲取用戶數據。
現在,我可以比較令牌,看看該用戶是否是登錄的用戶。
但這不是絕對安全的。 如果有人獲得此令牌,則他可以登錄。 這就是為什么要使用IP。 我不僅針對DB中的一個令牌檢查令牌,還針對IP對其進行檢查。 我創建MD5($ip.$email.$logindate)
是因為我知道所有數據,並對照從angular獲取的令牌進行檢查。 如果它是從其他IP發送的,則不會通過。
您還可以在authInterceptor
看到函數響應。 每當遇到身份驗證問題時,我都會發回HTTP代碼401
。 現在,作為響應,我知道身份驗證失敗。 我注銷用戶並將其重定向到站點的主頁。
現在,編碼非常簡單。 您只返回必須返回的內容,而不關心沒有經過身份驗證的用戶。
但是還有更多。 如果您需要某種類型的ACL,則可以根據需要進行設計。 在返回特定的RESTFull API方法的類中,您可以定義$acl
屬性並設置組的名稱。 在檢查身份驗證的位置,您也可以檢查ACL。
請在這里查看我的代碼,它是PHP后端和Angular前端
這是基本的想法,您當然可以圍繞它進行構建。
我不是PHP開發人員。 您不能在前端確保此內容。 以下是我們在NodeJs應用程序中使用的示例代碼,以驗證用戶是否具有有效的刪除權限。
router.patch('/:id', auth.hasRole(userEnums.roles.admin), controller.update);
router.post('/create', auth.hasRole(userEnums.roles.admin), controller.create);
//Checks if the user role meets the minimum requirements of the route
function hasRole(roleRequired) {
if (!roleRequired) throw new Error('Required role needs to be set');
return compose()
.use(isAuthenticated())
.use(function meetsRequirements(req, res, next) {
if (req.user.role.indexOf(roleRequired) !== -1) {
next();
}
else {
res.send(403);
}
});
}
auth.hasRole是簡單的方法/中間件,是一種咖喱設計模式。 它檢查use req,並檢查用戶是否具有有效的刪除權限。 如果用戶沒有管理員權限,則會返回並顯示未驗證錯誤消息。 這用於管理員和用戶關系。 最后,我們還使用另一種策略來驗證用戶。 假設我們已經公開了刪除API,那么任何人都可以刪除它。 在這種情況下,我們必須確保活動用戶必須是文檔的所有者。 在這種情況下,我們首先獲取文檔的所有者ID,並將其與請求的用戶ID匹配。 如果匹配,我們將刪除該文檔。
BlogPostApiService.destroy(id, _.curry(hasPermission)(req.user))
//hasPermission implementation
function hasPermission(user, blogPost) {
return user && (user.hasRole(UserEnums.roles.admin) || (user._id.toString() == blogPost.author.id.toString()));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.