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()
모든 액션에 대해마지막으로 수정된 리소스 복사본을 반환합니다.
그tokenWrapper
method는 우선 기존 자원 액션의 복사본을 만듭니다.이 복사본은 뒤에 밑줄이 있다.그렇게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 |