AngularJS: $resource 요청과 함께 인증 토큰을 보내려면 어떻게 해야 합니까?
API에서 리소스를 요청할 때 인증 토큰을 보내고 싶습니다.
$resource를 사용하여 서비스를 구현했습니다.
factory('Todo', ['$resource', function($resource) {
return $resource('http://localhost:port/todos.json', {port:":3001"} , {
query: {method: 'GET', isArray: true}
});
}])
인증 토큰을 저장하는 서비스가 있습니다.
factory('TokenHandler', function() {
var tokenHandler = {};
var token = "none";
tokenHandler.set = function( newToken ) {
token = newToken;
};
tokenHandler.get = function() {
return token;
};
return tokenHandler;
});
토큰을 보내고 싶습니다.tokenHandler.get경유로 송신되는 모든 요구는Todo서비스.특정 액션의 호출에 넣어 보낼 수 있었습니다.예를 들어 다음과 같이 동작합니다.
Todo.query( {access_token : tokenHandler.get()} );
단, access_token을 파라미터로 정의하고 싶습니다.Todo모든 콜에 대해 전송해야 하기 때문에 서비스를 제공합니다.그리고 드라이를 개선합니다.단, 공장 내의 모든 것은 1회만 실행되므로 access_token은 공장 정의 전에 사용할 수 있어야 하며 이후 변경할 수 없습니다.
동적으로 갱신된 요청 파라미터를 서비스에 추가할 수 있는 방법이 있습니까?
앤디 조슬린 덕분이야나는 자원 활동을 포장하는 그의 아이디어를 골랐다.현재 리소스 서비스는 다음과 같습니다.
.factory('Todo', ['$resource', 'TokenHandler', function($resource, tokenHandler) {
var resource = $resource('http://localhost:port/todos/:id', {
port:":3001",
id:'@id'
}, {
update: {method: 'PUT'}
});
resource = tokenHandler.wrapActions( resource, ["query", "update"] );
return resource;
}])
보시다시피 리소스는 처음부터 일반적인 방식으로 정의되어 있습니다.이 예에서는 다음과 같은 커스텀액션이 포함되어 있습니다update그 후 리소스가 반환되면 덮어쓰게 됩니다.tokenHandler.wrapAction()리소스 및 작업 배열을 매개 변수로 사용하는 메서드입니다.
후자의 메서드는 실제로 모든 요구에 인증 토큰을 포함하는 액션을 랩하고 변경된 리소스를 반환합니다.그럼 그 코드를 보겠습니다.
.factory('TokenHandler', function() {
var tokenHandler = {};
var token = "none";
tokenHandler.set = function( newToken ) {
token = newToken;
};
tokenHandler.get = function() {
return token;
};
// wrap given actions of a resource to send auth token with every
// request
tokenHandler.wrapActions = function( resource, actions ) {
// copy original resource
var wrappedResource = resource;
for (var i=0; i < actions.length; i++) {
tokenWrapper( wrappedResource, actions[i] );
};
// return modified copy of resource
return wrappedResource;
};
// wraps resource action to send request with auth token
var tokenWrapper = function( resource, action ) {
// copy original action
resource['_' + action] = resource[action];
// create new action wrapping the original and sending token
resource[action] = function( data, success, error){
return resource['_' + action](
angular.extend({}, data || {}, {access_token: tokenHandler.get()}),
success,
error
);
};
};
return tokenHandler;
});
보다시피wrapActions()method는 해당 파라미터에서 리소스 복사본을 생성하여 루프를 수행합니다.actions다른 함수를 호출하는 배열tokenWrapper()모든 액션에 대해마지막으로 수정된 리소스 복사본을 반환합니다.
그tokenWrappermethod는 우선 기존 자원 액션의 복사본을 만듭니다.이 복사본은 뒤에 밑줄이 있다.그렇게query()된다_query()그 후, 새로운 메서드가 원래의 메서드를 덮어씁니다.query()방법.이 새로운 메서드는 랩됩니다._query()(Andy Joslin에 의해 제안되었듯이) 이 액션을 통해 전송되는 모든 요구와 함께 인증 토큰을 제공합니다.
이 접근방식의 장점은 모든 angularj 자원(get, query, save 등)과 함께 제공되는 사전 정의된 액션을 재정의할 필요 없이 사용할 수 있다는 것입니다.또한 코드의 나머지 부분(예를 들어 컨트롤러 내)에서는 기본 액션 이름을 사용할 수 있습니다.
또 다른 방법은 HTTP 대행 수신기를 사용하여 "매직" 인가 헤더를 현재 OAuth 토큰으로 대체하는 것입니다.아래 코드는 OAuth에 따라 다르지만, 이 문제를 해결하는 것은 독자에게 간단한 연습입니다.
// Injects an HTTP interceptor that replaces a "Bearer" authorization header
// with the current Bearer token.
module.factory('oauthHttpInterceptor', function (OAuth) {
return {
request: function (config) {
// This is just example logic, you could check the URL (for example)
if (config.headers.Authorization === 'Bearer') {
config.headers.Authorization = 'Bearer ' + btoa(OAuth.accessToken);
}
return config;
}
};
});
module.config(function ($httpProvider) {
$httpProvider.interceptors.push('oauthHttpInterceptor');
});
이 접근방식은 매우 마음에 듭니다.
http://blog.brunoscopelliti.com/authentication-to-a-restful-web-service-in-an-angularjs-web-app
여기서 토큰은 항상 래퍼 없이 요청 헤더 내에서 자동으로 전송됩니다.
// Define a new http header
$http.defaults.headers.common['auth-token'] = 'C3PO R2D2';
래퍼 기능을 만들 수 있습니다.
app.factory('Todo', function($resource, TokenHandler) {
var res= $resource('http://localhost:port/todos.json', {
port: ':3001',
}, {
_query: {method: 'GET', isArray: true}
});
res.query = function(data, success, error) {
//We put a {} on the first parameter of extend so it won't edit data
return res._query(
angular.extend({}, data || {}, {access_token: TokenHandler.get()}),
success,
error
);
};
return res;
})
저도 이 문제를 해결해야 했어요.이것이 우아한 솔루션이라고는 생각하지 않지만 효과가 있고 코드 행이 2개 있는 경우:
예를 들어 Session Service에서 인증을 받은 후 서버에서 토큰을 얻을 수 있습니다.그런 다음 다음과 같은 메서드를 호출합니다.
angular.module('xxx.sessionService', ['ngResource']).
factory('SessionService', function( $http, $rootScope) {
//...
function setHttpProviderCommonHeaderToken(token){
$http.defaults.headers.common['X-AUTH-TOKEN'] = token;
}
});
그 후 $resource 및 $http로부터의 모든 요청은 헤더에 토큰이 포함됩니다.
다른 솔루션은 resource.bind(additional Param Defaults)를 사용하여 추가 파라미터로 바인드된 리소스의 새 인스턴스를 반환하는 것입니다.
var myResource = $resource(url, {id: '@_id'});
var myResourceProtectedByToken = myResource.bind({ access_token : function(){
return tokenHandler.get();
}});
return myResourceProtectedByToken;
access_token 함수는 리소스에 대한 액션이 호출될 때마다 호출됩니다.
가 당신의하고 있는 것 해 주세요으로 말하면, 이 질문의 말씀드리겠습니다.access_token, 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」를해 본 적이 있습니까?TokenHandler 입력하다Todo모??
// app
var app = angular.module('app', ['ngResource']);
// token handler
app.factory('TokenHandler', function() { /* ... */ });
// inject the TokenHandler
app.factory('Todo', function($resource, TokenHandler) {
// get the token
var token = TokenHandler.get();
// and add it as a default param
return $resource('http://localhost:port/todos.json', {
port: ':3001',
access_token : token
});
})
요.Todo.query() 붙을 예요.?token=none토큰 플레이스 홀더를 추가하려면 물론 다음을 수행합니다.
http://localhost:port/todos.json/:token
이것이 도움이 되기를 바랍니다:)
수락하신 답변에 따라 Todo 오브젝트로 토큰을 설정하기 위해 리소스를 확장할 것을 제안합니다.
.factory('Todo', ['$resource', 'TokenHandler', function($resource, tokenHandler) {
var resource = $resource('http://localhost:port/todos/:id', {
port:":3001",
id:'@id'
}, {
update: {method: 'PUT'}
});
resource = tokenHandler.wrapActions( resource, ["query", "update"] );
resource.prototype.setToken = function setTodoToken(newToken) {
tokenHandler.set(newToken);
};
return resource;
}]);
이렇게 하면 ToDo 객체를 사용할 때마다 TokenHandler를 Import할 필요가 없으며 다음을 사용할 수 있습니다.
todo.setToken(theNewToken);
의 변경은 디폴트액션이 빈 디폴트액션을 입니다.wrapActions:
if (!actions || actions.length === 0) {
actions = [];
for (i in resource) {
if (i !== 'bind') {
actions.push(i);
}
}
}
언급URL : https://stackoverflow.com/questions/11176330/angularjs-how-to-send-auth-token-with-resource-requests
'sourcecode' 카테고리의 다른 글
| mongodb에서 여러 어레이 요소를 업데이트하는 방법 (0) | 2023.03.19 |
|---|---|
| 빈 배열을 입력으로 사용하는 'useCallback'과 두 번째 매개 변수를 사용하지 않는 'useCallback'의 차이점은 무엇입니까? (0) | 2023.03.19 |
| Woocommerce에서 판매 중인 제품에 "세일" 제품 카테고리 추가 (0) | 2023.03.19 |
| jQuery click() 이벤트가 로드된 AJAX에서 실행되지 않음HTML 요소 (0) | 2023.03.19 |
| Angularjs $q.all (0) | 2023.03.19 |