2016-11-01 4 views
1

C#을 처음 사용하는 경우에도 HttpClient 라이브러리를 제대로 사용하지 않을 것입니다. Nest API와 함께 인증을 시도하여 서모 스탯에 대한 요청을 읽고 쓸 수 있습니다. 아래는 내가 인증을 사용하고있는 코드는 다음과 같습니다C# Nest API와 작동합니다. HttpClient를 사용하여 안정적인 인증을 얻었습니다.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using Microsoft.AspNetCore.Mvc; 
using System.Net.Http; 
using System.Net.Http.Headers; 


namespace iConnect.Controllers 
{ 
    public class NestController : Controller 
    { 
     static HttpClient client = new HttpClient(); 

     public IActionResult Index() 
     { 
      return View(); 
     } 

     public async Task<HttpResponseMessage> GetNestAuthCode() 
     { 
      // Nest Pin Code 
      String pincode = "MYPING"; 
      String clientID = "My-Client-ID"; 
      String clientSecret = "MySecretString"; 
      String grantType = "authorization_code"; 

      client.BaseAddress = new Uri("https://api.home.nest.com"); 
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
      var request = new HttpRequestMessage(HttpMethod.Post, "/oauth2/access_token"); 

      var data = new List<KeyValuePair<string, string>> 
      {     
       new KeyValuePair<string, string>("code", pincode) 
       , new KeyValuePair<string, string>("client_id", clientID) 
       , new KeyValuePair<string, string>("client_secret", clientSecret) 
       , new KeyValuePair<string, string>("grant_type", grantType) 
      }; 

      //var content = new FormUrlEncodedContent(data); 
      //await content.ReadAsByteArrayAsync(); 
      //content.Add(data); 
      request.Content = new FormUrlEncodedContent(data); 

      //HttpResponseMessage response = await client.PostAsync(client.BaseAddress, content); 

      HttpResponseMessage response = await client.SendAsync(request); 

      return response; 
     } 
    } 
} 

내가 로컬 호스트로 이동 : 모든 지원이 크게 감사합니다

{ 
    "version":{ 
     "major":1, 
     "minor":1, 
     "build":-1, 
     "revision":-1, 
     "majorRevision":-1, 
     "minorRevision":-1 
    }, 
    "content":{ 
     "headers":[ 
     { 
      "key":"Content-Type", 
      "value":[ 
       "application/json" 
      ] 
     } 
     ] 
    }, 
    "statusCode":400, 
    "reasonPhrase":"Bad Request", 
    "headers":[ 
     { 
     "key":"Connection", 
     "value":[ 
      "keep-alive" 
     ] 
     } 
    ], 
    "requestMessage":{ 
     "version":{ 
     "major":1, 
     "minor":1, 
     "build":-1, 
     "revision":-1, 
     "majorRevision":-1, 
     "minorRevision":-1 
     }, 
     "content":{ 
     "headers":[ 
      { 
       "key":"Content-Type", 
       "value":[ 
        "application/x-www-form-urlencoded" 
       ] 
      }, 
      { 
       "key":"Content-Length", 
       "value":[ 
        "130" 
       ] 
      } 
     ] 
     }, 
     "method":{ 
     "method":"POST" 
     }, 
     "requestUri":"https://api.home.nest.com/oauth2/access_token", 
     "headers":[ 
     { 
      "key":"Accept", 
      "value":[ 
       "application/json" 
      ] 
     } 
     ], 
     "properties":{ 

     } 
    }, 
    "isSuccessStatusCode":false 
} 

: 9387/둥지/GetAuthCode, 나는 다음과 같은 JSON 응답을 얻을. 고맙습니다.

편집 : 나는 다음과 같은 변화를 만들어 한

(내가 기대하지 않은) 다음과 같은 응답을 얻을 :

코드 :

public async Task<ActionResult> GetNestAuthCode() 
     { 
      // Nest Pin Code 
      String pincode = "MYPING"; 
      String clientID = "My-Client-ID"; 
      String clientSecret = "MySecretString"; 
      String grantType = "authorization_code"; 

      client.BaseAddress = new Uri("https://api.home.nest.com"); 
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
      //var request = new HttpRequestMessage(HttpMethod.Post, "/oauth2/access_token"); 

      var data = new List<KeyValuePair<string, string>> 
      {     
       new KeyValuePair<string, string>("code", pincode) 
       , new KeyValuePair<string, string>("client_id", clientID) 
       , new KeyValuePair<string, string>("client_secret", clientSecret) 
       , new KeyValuePair<string, string>("grant_type", grantType) 
      }; 

      //var content = new FormUrlEncodedContent(data); 
      //await content.ReadAsByteArrayAsync(); 
      //content.Add(data); 
      //request.Content = new FormUrlEncodedContent(data); 

      //HttpResponseMessage response = await client.PostAsync(client.BaseAddress, content); 

      var response = await client.PostAsync("oauth2/access_token", 
        new FormUrlEncodedContent(data)); 

      var content = await response.Content.ReadAsStringAsync(); 

      return Content(content); 
     } 

응답 :

{"error":"oauth2_error","error_description":"authorization code not found","instance_id":"f64d5268-8bec-4799-927c-e53454ed96d5"} 
+0

인증 부분에 대해 .NET 용 기존 OAuth2 클라이언트 라이브러리 (예 : https://github.com/versionone/OAuth2Client.Net)를 사용해 보셨습니까?직접 OAuth2를 얻는 것보다 쉽습니다. – cynic

답변

1

전적으로 답장을 보내고 있습니다. 전자 메시지를 모든 속성 및 값과 함께 동작 메서드에서 다시 가져옵니다. 대신, 당신은 그 내용을 읽고 그것을 반환해야합니다. 원할 경우 HttpClient 오른쪽 here에 내장 된을 사용하는 방법에 대한 좋은 기사를 찾을 수 있습니다. 난 아직도 반환 형식 같은 IActionResult (또는 실제로 Task<IActionResult>)를 사용하고 있습니다 ...

  • public async Task<IActionResult> GetNestAuthCode() 
    { 
        // HttpClient setup... 
    
        var content = new FormUrlEncodedContent(new[] 
        { 
         new KeyValuePair<string, string>("code", "MYPING"), 
         new KeyValuePair<string, string>("client_id", "My-Client-ID"), 
         new KeyValuePair<string, string>("client_secret", "MySecretString"), 
         new KeyValuePair<string, string>("grant_type", "authorization_code") 
        }); 
    
        var response = await client.PostAsync("oauth2/access_token", content); 
    
        // Or check instead with IsSuccessStatusCode 
        response.EnsureSuccessStatusCode(); 
    
        // ReadAsStringAsync() is just an example here 
        var responseContent = await response.Content.ReadAsStringAsync(); 
    
        return Content(responseContent); 
    } 
    

    참고 : 나는 어떻게 할 것인지

    은 다음과 같다. 응답 개체를 반환하면 안됩니다.

  • 내가 직접 대신 첫째는 HttpRequestMessage을 구축하고 SendAsync()를 사용하는 FormUrlEncodedContent과 관련된 내용으로 PostAsync() 방법을 사용하고 있습니다.
  • 요청이 성공했는지 확인하는 것도 잊지 마십시오! 그렇지 않으면 작업 메서드에서 오류 메시지가 반환 될 수 있습니다.
  • 예를 들어 ReadAsStringAsync()return Content()을 사용하고 있습니다.

400 Bad Request을 반환하기 때문에 Nest API에 대한 귀하의 요청에 문제가 있습니다. 내용의 오류 메시지에서 정확히 무엇을 파생시킬 수 있어야합니다. ;)

편집

나는 둥지 API에서 매우 빠른 모습을했고, 나는 당신이 code에 대한 잘못된 값을주는 것 같아요. PIN 코드를 지정하는 대신 액세스 토큰 (예 : here)으로 교환하기 전에 먼저 다른 API 메소드를 호출하여 인증 코드를 검색해야한다고 생각합니다.

+0

도움을 주셔서 감사합니다. .NET Core에 대해 보내 주신 내용을 일부 수정해야했지만 지금은 기대했던 것과 다른 결과를 얻고 있습니다. 위의 원래 질문을 수정했습니다. – Ronny

+0

@ 로니, 천만에요! PostAsJsonAsync() 확장 메소드의 경우 ASP.NET 코어 버전을 간단히 살펴 보았습니다. Microsoft.AspNet.WebApi.Client 패키지를 포함해야합니다. 결과적으로 Nest API에서 되돌아 오는 결과입니다. 당신의'HttpClient' 인스턴스는 실제로 올바르게 설정되어 있습니다 만, 당신은 당신의 요청에 잘못된 것을하고 있습니다. 이에 대한 Nest API 문서를 확인하는 것이 좋습니다. – DeveTho

+0

왜 요청 인코딩을 JSON으로 바꾸라고 조언하고 있습니까? 그것은 분명하지 않습니다. [docs에서] (https://developers.nest.com/documentation/cloud/rest-quick-guide#post-call) 그게 맞지 않습니다. OP가 수행 한 URL 인코딩이되어야합니다. –