사용자 상호 작용 없이 OneDrive API(예: 배치 프로그램(.NET C# 버전))(추가 사용 라이브러리 없음)

페이지 업데이트 :
페이지 생성 날짜 :

운영 환경

비주얼 스튜디오
  • 비주얼 스튜디오 2022
.그물
  • .그물 8
Microsoft 인증 API
  • 2.0 오어스 2
마이크로소프트 원드라이브 API
  • 1.0
Microsoft 계정 유형
  • 회사 또는 학교 계정

필수 구성 요소

비주얼 스튜디오
  • 버전 중 하나
.그물
  • 버전 중 하나
Microsoft 인증 API
  • 2.0 오어스 2
마이크로소프트 원드라이브 API
  • 1.0
Microsoft 계정 유형
  • 회사 또는 학교 계정

이 이벤트의 목적에 대해

이제 OneDrive API를 사용하여 프로그래밍 방식으로 OneDrive에 파일을 업로드하고 다운로드할 수 있도록 준비합니다. 이 문서에서는 OneDrive API로 수행할 수 있는 작업에 대해 설명하므로 OneDrive API로 수행할 수 있는 작업에 대해서는 다루지 않습니다. 그러나 연결할 수 있는 한 API 설명서를 읽고 그 후에 적용할 수 있습니다.

프로그램 실행 방법

OneDrive에 대한 액세스는 웹 응용 프로그램, 데스크톱 응용 프로그램 또는 콘솔 응용 프로그램과 같은 프로그램 형식에 의존하지 않으며 다양한 프로그램에서 실행할 수 있습니다. 이 경우 콘솔 응용 프로그램을 만들고 사용자 작업 없이 자동으로 실행합니다.

Microsoft 계정에는 어떤 종류가 있나요?

Microsoft 계정을 만들어 본 적이 있다면 본 적이 있을 것입니다. Microsoft 계정에는 개인 Microsoft 계정과 회사 또는 학교 계정의 두 가지 주요 유형이 있습니다. OneDrive는 Microsoft 계정에 연결되어 있지만 OneDrive 유형은 위에 나열된 계정 유형에 따라 약간 다릅니다.

당분간 OneDrive API는 위의 두 가지 유형의 계정 모두에서 사용할 수 있습니다. 이 프로그램에서는 "콘솔 응용 프로그램으로 생성되어 사용자 조작없이 실행"형태로, "회사 또는 학교 계정" 계정의 Microsoft 계정으로만 사용할 수 있습니다. 이는 인증 방법의 차이 때문입니다.

인증 방법 정보

먼저 프로그래밍 방식으로 OneDrive에 액세스하려면 인증해야 합니다. 위에서 언급했듯이 모든 프로그램이 OneDrive에 액세스할 수 있지만 API에 연결하기 위한 인증은 프로그램 실행 방식에 따라 다릅니다. 웹 응용 프로그램 및 데스크톱 응용 프로그램은 사용자 상호 작용에 의해 인증될 수 있습니다. 사용자가 백그라운드에서 실행되는 콘솔 응용 프로그램에서는 조작할 수 없기 때문에 인증 방법도 위와 다릅니다.

아직 찾아보지 못해 자세한 이유는 모르겠지만, 떠오르면 보안과 계정 관리 때문인 것 같다. 이것은 이미 사양이라고 말할 수 있으므로 "개인 Microsoft 계정"과 연결된 OneDrive에 프로그래밍 방식으로 액세스하려는 경우, 백그라운드에서 실행되는 프로그램 이외의 프로그램을 사용하거나, 사용자 조작을 포함한 인증 방법으로 콘솔 응용 프로그램을 실행하는 것 외에는 선택의 여지가 없다고 생각합니다.

지금은 라이브러리를 사용하여 OneDrive API에 액세스하지 않습니다

OneDrive API에 대한 액세스는 "Microsoft Graph"라는 라이브러리를 사용하여 비교적 쉽게 처리할 수 있습니다. 이 경우 API의 URL에 직접 액세스하여 실행하는 방법을 사용합니다. 조금 번거롭지만 라이브러리를 사용하지 않기 때문에 non-.NET 프로그램이 같은 방식으로 OneDrive API에 액세스할 수 있다는 장점이 있습니다. 또한 라이브러리의 다른 버전으로 인해 코드가 변경되는 단점을 방지합니다.

다른 팁에서 Microsoft Graph를 사용하는 방법을 보여 드리겠습니다.

전제 조건

  • 회사 또는 학교 계정에 대한 Microsoft 계정이 있습니다.
  • 위에 나열된 Microsoft 계정과 연결된 OneDrive(예: OneDrive Business)를 사용할 수 있습니다.
  • Visual Studio 2022 설치됨

Azure에서 Microsoft 계정 또는 OneDrive에 액세스하도록 응용 프로그램 설정Set up your application to access your Microsoft account or OneDrive in Azure

다음 URL에서 Azure에 로그인합니다.

위의 검색 필드에서 "app registrations"를 입력하고 선택합니다.

New Registration(새 등록)을 클릭합니다.

"이름"의 내용은 임의적입니다. 설명이 포함된 이름을 입력하십시오.

"개인 Microsoft 계정만" 이외의 "지원되는 계정 유형"을 선택합니다. 위에서 언급했듯이 이 인증은 조직에 속한 계정에서만 사용할 수 있기 때문입니다. 이 경우 "모든 조직 디렉터리의 계정(모든 Microsoft Entra ID 테넌트 - 다중 테넌트) 및 개인 Microsoft 계정(Skype, Xbox 등)"을 선택했습니다.

"리디렉션 URI"는 이번에는 사용되지 않으므로 입력할 필요가 없습니다.

완료되면 "등록" 버튼을 클릭합니다.

만든 앱 등록의 요약 페이지로 이동하므로 애플리케이션(클라이언트) ID 및 디렉터리(테넌트) ID를 복사합니다. 나중에 이 값을 사용합니다.

왼쪽 메뉴의 관리 범주에서 "인증서 및 비밀"을 선택하고 중간 탭에서 "클라이언트 암호"가 선택되어 있는지 확인합니다. New Client Secret(새 클라이언트 암호)을 클릭합니다.

설명 입력은 선택 사항입니다. 계속 이용을 희망하시는 경우는, 이용 목적을 명확하게 알 수 있는 설명을 동봉해 주세요.

"만료 날짜"는 이 클라이언트 암호가 유효한 기간입니다. 이번에는 테스트 목적이므로 90 일입니다 만, 사용 목적에 맞게 설정하십시오.

클라이언트 암호를 만들면 목록에 추가됩니다. 여기에서는 "Value" 열의 값을 사용할 것이므로 복사하십시오. 이 값은 나중에 복사할 수 없습니다.

그런 다음 왼쪽 메뉴의 관리 범주에서 "API 권한"을 선택하고 중간에 있는 "권한 추가"를 클릭합니다.

API 권한 요청에서 Microsoft Graph를 클릭합니다.

Allow Application(응용 프로그램 허용)을 클릭합니다. 개인 Microsoft 계정에는 이 옵션을 사용할 수 없습니다.

아래에 권한 목록이 표시되므로 검색 필드를 사용하여 다음 항목을 확인하십시오.

  • 파일.ReadWrite.All

OneDrive만 사용하려는 경우 충분하지만 다른 항목에 액세스하려면 권한을 추가하십시오. OneDrive에 액세스하는 데 필요한 권한은 아래 공식 페이지에서 찾을 수 있습니다.

선택을 마쳤으면 Add Permissions 버튼을 클릭합니다.

추가된 항목이 목록에 추가되고 "유형"은 "응용 프로그램"입니다. 그러나 "상태"가 "XXXX에 부여되지 않음"이므로 "XXXX에 관리자 동의 부여"를 클릭합니다. (XXXX는 조직의 이름입니다.)

Yes(예)를 클릭합니다.

부여된 상태로 변경됩니다.

그건 그렇고, 이번에는 사용하지 않을 것이기 때문에 처음부터 거기에있는 "위임 된 User.Read"를 삭제할 수 있습니다. "User.Read"를 응용 프로그램으로 추가한 경우 사용합니다.

사용자 ID 확인

대상 사용자가 가지고 있는 OneDrive에 액세스하므로 사전에 사용자 ID를 확인하십시오.

Microsoft Entra ID 그리고 그것을 엽니 다.

왼쪽 메뉴에서 사용자를 선택합니다.

사용자 목록이 표시되므로 대상 사용자를 클릭합니다.

"개체 ID"는 사용자 ID가 되므로 기록해 둡니다.

콘솔 응용 프로그램 만들기Create a console application

Visual Studio를 시작하고 콘솔 응용 프로그램에 대한 프로젝트를 만듭니다. Visual Studio 외부에서 만들 수 있지만 지금은 Visual Studio를 사용하겠습니다.

위치 및 프로젝트 이름은 선택 사항입니다. 이 경우 프로젝트 이름은 OneDriveApiDotNetClientCredentialsHttpClient 입니다.

이번에는 코드를 Program.cs 나누지 않고 위에서 엇갈리게 작성하기 때문에 움직임을 확인할 수 있으면 필요에 따라 코드를 나누어 다시 작성하십시오.

using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.Json;
using System.Web;
using System.Xml;

사용할 네임스페이스를 설명합니다.

// 認証結果を格納するクラスです
public record TokenResponse(string token_type, int expires_in, int ext_expires_in, string access_token);

이 클래스는 인증 후 토큰 정보를 받는 데 사용됩니다. Program.cs , 코드 끝에 적어주세요. 이 클래스를 다른 파일로 분리할 수 있습니다.

// JSON 文字列を整形するメソッド
static string ConvertToIndentedJson(string json)
{
  byte[] buffer = Encoding.UTF8.GetBytes(json);
  using MemoryStream stream = new();
  using XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, true, true);
  using XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(buffer, XmlDictionaryReaderQuotas.Max);
  writer.WriteNode(reader, true);
  writer.Flush();
  return Encoding.UTF8.GetString(stream.ToArray());
}

이것은 들여쓰기를 사용하여 API에서 받은 JSON 텍스트를 형식화하는 마법 같은 방법입니다. 인터넷에서 가져온 코드이기 때문에 자세한 내용은 설명하지 않습니다.

// 各種 ID などの定義
var clientId = "XXXXXXXX";      // クライアント ID
var tenantId = "XXXXXXXX";      // テナント ID
var clientSecret = "XXXXXXXX";  // クライアント シークレット
var userId = "XXXXXXXX";        // ユーザー ID
var accessToken = "";           // アクセストークン

각각에 대해 Azure에서 얻은 ID를 설정합니다. accessToken 는 OneDrive에 액세스하기 위한 임시 토큰이므로 런타임에 설정됩니다.

// 各種 URL の定義
var urlToken = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
var urlOneDriveGetRootFolders = $"https://graph.microsoft.com/v1.0/users/{userId}/drive/root/children";

인증을 위한 API URL 및 OneDvie의 루트에 있는 폴더 목록을 가져오기 위한 API URL. OneDrive API에 대한 액세스를 확인하는 방법에 대한 설명이므로 OneDrive API의 내용은 설명하지 않겠습니다. OneDrive API에 액세스 할 수 있으면 업로드 및 다운로드가 응용 프로그램이므로 그렇게 어렵지 않다고 생각합니다.

// 使いまわすので最初に定義しておく
HttpClient httpClient = new();

지정된 URL에 HttpClient 요청하기 위해 a를 생성했습니다.

// 「Name1=Value1&Name2=Value2...」形式のクエリパラメータ文字列を作成する
var valueDict = new Dictionary<string, string>
{
    { "client_id", clientId },
    { "scope", "https://graph.microsoft.com/.default" },
    { "client_secret", clientSecret },
    { "grant_type", "client_credentials" },
};
var valueQS = string.Join("&", valueDict.Select(x => string.Format("{0}={1}", x.Key, HttpUtility.UrlEncode(x.Value))));
Console.WriteLine($"valueQS={valueQS}");

먼저 데이터를 사용하여 인증 API에 요청하므로 해당 데이터를 준비합니다. 전송할 데이터의 형식은 "Name1=Value1&Name2=Value2..." 형식의 쿼리 매개 변수 문자열이므로 사전에 생성된 다음 쿼리 매개 변수 문자열로 변환됩니다.

전송할 매개 변수에는 4개가 있습니다.

Example 매개 변수 이름
client_id 앱 등록에서 얻은 클라이언트 ID를 설정합니다.
범위 클라이언트 암호를 사용한 인증은 고정되어 있습니다 https://graph.microsoft.com/.default .
client_secret 앱 등록에서 얻은 클라이언트 암호의 값을 설정합니다.
grant_type 클라이언트 시크릿 client_credentials 을 사용한 인증이기 때문에

자세한 내용은 다음 공식 웹 사이트를 참조하십시오.

// 認証処理
using (HttpRequestMessage request = new(HttpMethod.Post, urlToken))
{
  request.Content = new StringContent(valueQS, Encoding.UTF8, "application/x-www-form-urlencoded");

  // データを送信し結果を受け取る
  using var response = httpClient.SendAsync(request).Result;

  Console.WriteLine($"IsSuccessStatusCode={response.IsSuccessStatusCode}");
  Console.WriteLine($"StatusCode={response.StatusCode}");
  Console.WriteLine($"ReasonPhrase={response.ReasonPhrase}");

  if (response.IsSuccessStatusCode == false)
  {
    Console.WriteLine("トークンの取得に失敗しました。");
    return;
  }

  // レスポンスからアクセストークンを受け取る。
  var tokenResultJson = response.Content.ReadAsStringAsync().Result;
  Console.WriteLine($"tokenResultJson={ConvertToIndentedJson(tokenResultJson)}");

  var tokenResult = JsonSerializer.Deserialize<TokenResponse>(tokenResultJson) ?? throw new Exception("JSON をデシリアライズできませんでした。");
  accessToken = tokenResult.access_token;
}

HttpClient 을 클릭하여 인증 API에 요청합니다. HttpClient 일반적인 사용법이기 때문에 그다지 주의를 기울일 필요가 없다고 생각합니다.

전송할 데이터는 UTF8로 인코딩되어야 하며 Content-Type application/x-www-form-urlencoded 은 . 방법은 입니다 POST .

응답이 IsSuccessStatusCode 확인되고 성공적으로 처리되면 결과를 JSON 문자열로 받게 됩니다. 수신하는 JSON에는 다음과 같은 매개 변수가 있습니다.

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "ext_expires_in": 3599,
  "access_token": "XXXXXXXXXXXXXXX"
}

여기서 access_token 우리는 . OneDrive API와 함께 이 값을 사용합니다. 다른 매개 변수는 무시할 수 있지만access_token 의 만료 날짜를 알고 싶다면 을 사용합니다 expires_in .

JSON 문자열로 사용하기 어렵기 때문에 JsonSerializer.Deserialize 로 deserialize한 다음 access_token 얻습니다.

// OneDrive 処理
using (HttpRequestMessage request = new(HttpMethod.Get, urlOneDriveGetRootFolders))
{
  // アクセストークンをヘッダーに追加する
  request.Headers.Add("Authorization", "Bearer " + accessToken);

  // OneDrive API にリクエスト
  using var response = httpClient.SendAsync(request).Result;

  Console.WriteLine($"IsSuccessStatusCode={response.IsSuccessStatusCode}");
  Console.WriteLine($"StatusCode={response.StatusCode}");
  Console.WriteLine($"ReasonPhrase={response.ReasonPhrase}");

  if (response.IsSuccessStatusCode == false)
  {
    Console.WriteLine("OneDrive へのアクセスに失敗しました。");
    return;
  }

  // レスポンスからアクセストークンを受け取る。
  var apiResultJson = response.Content.ReadAsStringAsync().Result;
  Console.WriteLine($"apiResultJson={ConvertToIndentedJson(apiResultJson)}");
}

마지막으로 액세스 토큰을 사용하여 OneDrive API에 요청합니다. 이 메서드는 를 지정 GET 하지만 API 유형에 따라 다르므로 OneDrive API 설명서를 확인하세요.

헤더에 액세스 토큰을 추가합니다. 키를 로 Authorization 설정하고 값을 Bearer {アクセストークン} 형식으로 설정합니다.

요청을 하고 결과를 JSON 문자열로 받기만 하면 됩니다. 이제 OneDrive API에 액세스할 수 있는지 확인했으므로 JSON 문자열의 서식을 지정하고 콘솔에 인쇄하기만 하면 됩니다. 실제로 수신된 JSON을 역직렬화하고 그에 따라 처리합니다.

이번에 폴더 목록을 받았지만 JSON은 다음과 같다고 생각합니다.

{
  "@odata.context": "https:\/\/graph.microsoft.com\/v1.0\/$metadata#Collection(driveItem)",
  "value": [
    {
      "@microsoft.graph.Decorator": "decorator has been deprecated. Refer to folder.decorator",
      "createdBy": {
        "フォルダ作成者の情報":""
      },
      "createdDateTime": "2017-06-20T04:31:24Z",
      "eTag": "\"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX},1\"",
      "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "lastModifiedBy": {
        "フォルダ更新者の情報":""
      },
      "lastModifiedDateTime": "2017-06-20T04:31:24Z",
      "name": "フォルダ名",
      "parentReference": {
        "親フォルダの情報":""
      },
      "webUrl": "フォルダにアクセスできる URL",
      "cTag": "\"c:{5926E2DA-B7FF-4936-88A8-7908C378ECE2},0\"",
      "fileSystemInfo": {
        "createdDateTime": "2017-06-20T04:31:24Z",
        "lastModifiedDateTime": "2017-06-20T04:31:24Z"
      },
      "folder": {
        "childCount": 0
      },
      "size": 0,
      "specialFolder": {
        "name": "フォルダ名"
      }
    },
    :
  ]
}

모든 정보가 필요하다고 생각하지 않으므로 예를 value 들어 폴더 이름 만 가져 오려면 의 배열에서 매개 변수 name 만 가져올 수 있습니다.

요약

지금까지 제대로 작동한다면 배치 프로그램으로 OneDrive에 액세스할 수 있어야 합니다. 팁에 업로드 및 다운로드 방법이 요약되어 있는지는 모르겠지만 위에서 설명한 루트의 폴더 목록을 적용하면 기본적으로 작동합니다. API의 종류는 아래 공식 사이트에 정리되어 있으니 꼭 사용하고 싶은 API를 찾아 구현해 보세요.

감사

이번에는 OneDrive API 사용에 대해 몇 가지 질문이 있어서 질문을 했습니다.