> For the complete documentation index, see [llms.txt](https://teamsmiley.gitbook.io/devops/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://teamsmiley.gitbook.io/devops/go-lang/cli-azuread.md).

# azure ad cli

<https://teamsmiley.gitbook.io/devops/azure/active-directory>

여기에 이어서 만든다

기존 cli를 사용한다. <https://teamsmiley.gitbook.io/devops/go-lang/create-cli>

## 토큰 받아오기

```go
package httpApi

import (
  "context"
  "log"

  msal "github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
  "github.com/spf13/viper"
)

const scope = "api://xxxxx/.default"
const clientID = "xxxxx"

func getSecret() string {
  sec := viper.GetString("AZURE_SECRET")
  if sec == "" {
    log.Fatalf("AZURE_SECRET is missing, please configure it myctl configure --secret <secret>")
  }
  return sec
}

type tokenProvider struct{}

func (t *tokenProvider) OAuthToken() string {

  clientCredential, err := msal.NewCredFromSecret(getSecret())

  if err != nil {
    log.Fatalf("Couldn't create client app (%s)", err)
  }
  app, err := msal.New(clientID, clientCredential, func(o *msal.Options) {
    o.Authority = "https://login.microsoftonline.com/xxxxxxx"
  })
  if err != nil {
    log.Fatalf("Couldn't get application (%s)", err)
  }

  ctx := context.Background()
  token, err := app.AcquireTokenByCredential(ctx, []string{
    scope,
  })
  if err != nil {
    log.Fatalf("Error getting token (%s)", err)
  }
  return token.AccessToken
}
```

xxxx된 부분을 전부 수정해준다.

이제 http 리퀘스트를 보내기 전에 호출해서 토큰을 만든후 토큰을 http 리퀘스트에 넣어주면 된다.

```go
package httpApi

import (
  "encoding/json"
  "fmt"
  "io/ioutil"
  "net/http"
)

// json 을 만들어준다.
type ServerResponse struct {
  Id                      string `json:"id"`
  Memo                    string `json:"memo"`
  Cpu                     string `json:"cpu"`
  Memory                  *int   `json:"memory"`
  CpuModelName            string `json:"cpuModelName"`
}

func GetServer(query string) []ServerResponse {
  searchApi := "https://api.xxx.com/servers"

  oauthTokenProvider := new(tokenProvider) // auth 생성

  t := oauthTokenProvider.OAuthToken() // 토큰 발급

  r, err := http.NewRequest(http.MethodGet, searchApi, nil) // http request 생성
  if err != nil {
    panic(err)
  }

  r.Header.Add("Content-Type", "application/json") //헤더에 추가
  r.Header.Add("Authorization", "Bearer " + t) //헤더에 토큰 추가

  // appending to existing query args
  q := r.URL.Query()
  q.Add("searchquery", query)

  // assign encoded query string to http request
  r.URL.RawQuery = q.Encode()

  resp, err := http.DefaultClient.Do(r)

  if err != nil {
    panic(err)
  }

  defer resp.Body.Close()

  responseBody, err := ioutil.ReadAll(resp.Body) // 응답 결과 읽기

  if err != nil {
    panic(err)
  }

  fmt.Println("status : ", resp.Status)
  fmt.Println("responseBody : ", string(responseBody))

  // var result Server
  var jsonData []ServerResponse
  err = json.Unmarshal(responseBody, &jsonData) // json 파싱
  if err != nil {
    fmt.Println("http response unmarshal error", err)
    panic(err)
  }

  // fmt.Printf("result : %+v", jsonData) //결과 확인

  return jsonData
}
```

이제 myctl을 사용하면 언제든 토큰을 받아와서 그 토큰을 이용하여 api에 요청할수 있다.

이걸 사용하면 이제 api에 데이터를 읽을수도 쓸수도 있게 된다.
