programing

인증된 XMLHttpRequest 후에 브라우저가 인가 헤더를 재사용하지 않는 이유는 무엇입니까?

sourcejob 2023. 2. 8. 17:51
반응형

인증된 XMLHttpRequest 후에 브라우저가 인가 헤더를 재사용하지 않는 이유는 무엇입니까?

저는 Angular를 이용한 싱글 페이지 앱을 개발하고 있습니다.백엔드는 기본 인증을 필요로 하는 REST 서비스를 제공합니다.index.html 또는 스크립트를 취득하는 경우 인증이 필요하지 않습니다.

중 한 있다.<img>서, 「」는src「REST API」의 URL.<img>는 브라우저에 의해 처리되며 GET 요구에 대한 인가 헤더를 설정할 수 없습니다.자격 증명

다음과 같이 수정하려고 했습니다.

  1. ★★를 남기다img src 있다
  2. ready"에서 "Document ready"를 .XMLHttpRequest서비스하다/api/login권한 부여
  3. 을 완료하면, 「」를 합니다.img srcAtribute, 그때까지 브라우저가 Authorization 헤더를 후속 요구에 포함시키는 것을 알고 있을 것으로 생각됩니다.

됩니다.이치맞네요. (Angular의 은 다 맞는데 Angular의 이미지들이에요.ng-src같은 결과를 )

두 가지 질문이 있습니다.

  1. 가 정상적으로 종료된 후 모든 요구에 않은 입니까?XMLHttpRequest무슨 일입니까?
  2. 이 문제를 해결하려면 어떻게 해야 합니까?

@bergi가 요청의 세부사항을 요청했습니다.여기 있어요.

/api/로그인 요청

GET https://myserver/dev30281_WebServices/api/login HTTP/1.1
Accept: */*
Authorization: Basic <header here>
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)
Connection: Keep-Alive

응답(/api/login)

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 4
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 20 Dec 2013 14:44:52 GMT

/user/picture/2218에 대한 요청:

GET https://myserver/dev30281_WebServices/api/user/picture/2218 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)
Connection: Keep-Alive

그런 다음 웹 브라우저에 자격 증명을 입력하라는 메시지가 표시됩니다.입력 시 다음과 같은 응답이 나타납니다.

HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Content-Length: 3119
Content-Type: image/png
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 20 Dec 2013 14:50:17 GMT

기본 아이디어

JavaScript를 통해 이미지를 로드하여 사이트에 표시합니다.장점은 인증 credential이 HTML에 들어가지 않는다는 것입니다.이들은 JavaScript 측에서 저항할 것이다.

1단계: JS를 통해 영상 데이터 로드

이것이 기본적인 AJAX 기능입니다( 참조).

var xhr = new XMLHttpRequest();
xhr.open("GET", "your-server-path-to-image", true, "username", "password");

xhr.onload = function(evt) {
  if (this.status == 200) {
    // ...
  }
};

2단계: 데이터 포맷

그럼 이미지 데이터는 어떻게 표시할 수 있을까요?를 는, 은 HTML 에 를 합니다.src이미지 요소의 속성.여기서는 '정상' 대신 데이터 URI를 사용한다는 점을 제외하고 동일한 원칙을 적용할 수 있습니다.http(s)://파생상품

xhr.onload = function(evt) {
  if (this.status == 200) {
    var b64 = utf8_to_b64(this.responseText);
    var dataUri = 'data:image/png;base64,' + b64; // Assuming a PNG image

    myImgElement.src = dataUri;
  }
};

// From MDN:
// https://developer.mozilla.org/en-US/docs/Web/API/window.btoa
function utf8_to_b64( str ) {
    return window.btoa(unescape(encodeURIComponent( str )));
}

캔버스

를 그림으로 .<canvas>를할 수 됩니다.<img>이미지 속성 패널을 표시할 때 사용자가 긴 데이터 URI를 볼 수 있는 데이터 URI 및 데이터 URI.

구글의 각도 js.작가들도 비슷한 문제에 직면했다.은 다른 , 은 다른 도메인에 호스트되어 있습니다.img src=CSP를 이용하다그들은로 XHR을 든 XHR에 .img

그들은 그것을 어떻게 해결했는지 묘사한다.XHR을 사용하여 이미지를 가져온 후 HTML5 로컬 파일 시스템에 씁니다.로컬 파일시스템에 URL을 저장합니다.img의 »src명령어를 사용하여 속성을 지정합니다.

$http.get(doc.icon, {responseType: 'blob'}).success(function(blob) {
  console.log('Fetched icon via XHR');
  blob.name = doc.iconFilename; // Add icon filename to blob.
  writeFile(blob); // Write is async, but that's ok.
  doc.icon = window.URL.createObjectURL(blob);
  ...
}

왜 그랬는지 모르겠어요.이미지를 검색하기 위한 세션 토큰을 만드는 것은 불가능하다고 생각합니다.쿠키 헤더가 전송되겠지?교차출처 요청인가요?이 경우 withCredentials 속성을 설정합니까?혹시 P3P 같은 건가요?

또 다른 접근법은 이미지 요청을 프록시하는 엔드포인트를 사이트 백엔드에 추가하는 것입니다.따라서 자격 증명 없이 페이지가 요청할 수 있으며 백엔드가 인증을 처리합니다.자주 변경되지 않거나 사용자가 이미지를 업데이트하는 빈도를 알고 있는 경우 백엔드에서 이미지를 캐시할 수도 있습니다.이는 백엔드에서 매우 쉽게 수행할 수 있으며 프런트엔드가 단순해지고 자격 증명이 브라우저로 전송되지 않습니다.

문제가 인증일 경우 링크에는 인증되어 현재 브라우저 세션에서만 액세스할 수 있는 사용자에 대해 생성된 일회용 토큰이 포함될 수 있습니다.콘텐츠에 대한 안전한 접근을 의도된 사용자와 콘텐츠에 액세스할 수 있는 권한이 부여된 시간 동안만 허용합니다.그러나 이 작업에는 백엔드의 작업도 필요합니다.

저는 당신의 문제를 해결하기 위해 브라우저의 실제 작동 방식을 해킹하려 하지 말고 앱의 디자인을 바꿔야 한다고 생각합니다.

보안 URL에 대한 요청은 항상 img 태그 또는 javascript로 브라우저에 의해 이루어집니다.

사용자 조작 없이 자동으로 인증을 수행할 수 있는 경우 서버 측에서 인증을 수행할 수 있으며 이를 위해 클라이언트에 사용자+패스를 전송할 필요가 없습니다.이 경우 뒤에 있는 코드를 변경할 수 있습니다.https://myserver/dev30281_WebServices/api/user/picture/2218HTTP 인증을 사용하지 않고 인가를 실행하고 이미지를 제공하려면 사용자가 HTTP 인증을 요구할 권한이 있는 경우에만 403 금지 응답을 반환합니다(http://en.wikipedia.org/wiki/HTTP_403)).

다른 가능한 해결책은 보안 이미지가 포함된 페이지를 앱의 나머지 부분과 분리하는 것입니다.따라서 이론상으로는 두 개의 단일 페이지 앱이 있습니다.시큐어 부품에 액세스 하려면 , 유저가 로그인할 필요가 있습니다.하지만 당신의 경우 모든 요건을 설명하지 않았기 때문에 이것이 가능한지 잘 모르겠습니다.단, 인증을 필요로 하는 시큐어 리소스를 제공하는 경우에는 브라우저와 마찬가지로 사용자에게 자격 정보의 입력을 요구해야 합니다.

나는 항상 해석한다.

이전(또는 첫 번째 로그인 요청)에서 Cookie 헤더 값을 설정하고 다음 요청에서 해당 값을 보냅니다.

뭐 이런 거

첫 번째 요청 후 응답:

Date:Thu, 26 Dec 2013 16:20:53 GMT
Expires:-1
Pragma:no-cache
Set-Cookie:ASP.NET_SessionId=lb1nbxeyfhl5suii2hfchxpx; domain=.example.com; path=/; secure; HttpOnly
Vary:Accept-Encoding
X-Cdn:Served-By-Akamai
X-Powered-By:ASP.NET

다음 요청:

Accept:text/html,application/xhtml+xml
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,ru;q=0.6
Cache-Control:no-cache
Connection:keep-alive
Cookie:ASP.NET_SessionId=lb1nbxeyfhl5suii2hfchxpx;

보시다시피 ASP를 보냅니다.쿠키 헤더의 NET_SessionId="any value" 값입니다.서버가 php를 사용하는 경우 PHPSESSID="some value"를 해석해야 합니다.

를 사용해 보세요.Access-Control-Allow-Credentials: trueheader를 클릭합니다.IE에서 문제가 발생한 적이 있는데, 결국 이 헤더를 사용하게 되었습니다.또한 설정$httpProvider.defaults.headers.get = { 'withCredentials' : 'true' }각 js 코드에 있습니다.

이유에 대해서:Chrome과 Firefox를 사용해 봤는데 둘 다 브라우저 UI에서 직접 자격 증명을 입력경우(예: 브라우저에서 팝업)에만 기본 권한을 기억합니다.HTTP 요청은 동일하지만 자격 증명이 JavaScript에서 온 경우에는 기억되지 않습니다.일부러 그런 것 같은데, 표준에는 없는 것 같아요.

언급URL : https://stackoverflow.com/questions/20617720/why-doesnt-the-browser-reuse-the-authorization-headers-after-an-authenticated-x

반응형