Instagram APIを使ってアクセストークンを取得（してもらう）

# 内容

Instagram apiの仕様変更でSandboxモードでは他ユーザーの情報の取得ができなくなってしまいましたね。
クライアントワークで先方のID、PASSを聞くこと無くアクセストークンを取得する必要があったのでこちらのコードを作り使用してもらうことにしました。

こちらを使うことで**Client ID**と**Client Secret**からリクエストトークンの取得、リクエストトークンとアクセストークンの交換まで行われます。

※ただしアプリケーションの登録までは自力で行っていただく必要があります。
https://www.instagram.com/developer/clients/register/


```php

header("Content-Type: text/html; charset=UTF-8");

new Token;

class Token{

  private $client_id ;
  private $client_secret;
  private $redirect_uri = '[設置するURL（リダイレクトURLと同様）]';
	
    public function __construct(){

      session_start() ;

      if( !empty($_GET['code']) && !empty($_SESSION['state']) && !empty($_GET['state']) && $_SESSION['state'] == $_GET['state']) {

        $this->get_token();

      }elseif($_SERVER["REQUEST_METHOD"] == "POST"){
			
        $this->get_code();

      }else{
      
        $this->get_code_pre();
      
      }
    }

    private function get_code_pre(){

      //CSRF対策用セッション、stateパラメーターのみ使用可能
      session_regenerate_id( true ) ;
      $state = sha1( uniqid( mt_rand() , true ) ) ;
      $_SESSION['state'] = $state ;

      echo <<< EOM
      <form method="post" action="$this->redirect_uri">
      <label for="client_id">CLIENT ID</label>
      <input type="text" name="client_id" style=" width: 300px;"><br />
      <label for="client_secret">CLIENT SECRET</label>
      <input type="text" name="client_secret" style=" width: 300px;"><br />
      <input type="hidden" name="redirect_uri" value="$this->redirect_uri">
      <input type="hidden" name="setting">
      <input type="submit" value="送信する">
      </form>
EOM;
    }

    private function get_code(){
		
      $this->client_id = $_POST['client_id'];

      $_SESSION['client_id'] = $_POST['client_id'];
      $_SESSION['client_secret'] =$_POST['client_secret'];

      header( 'Location: https://api.instagram.com/oauth/authorize/?client_id='.$this->client_id.'&redirect_uri='.$this->redirect_uri. '&response_type=code&state='.$_SESSION['state']);
	
    }

    private function get_token(){
		
      $this->client_id = $_SESSION['client_id'];
      $this->client_secret = $_SESSION['client_secret'];

      $body = http_build_query( 
        array(
          'client_id' => $this->client_id ,
          'client_secret' => $this->client_secret ,
          'grant_type' => 'authorization_code' ,
          'redirect_uri' => $this->redirect_uri ,
          'code' => $_GET['code'] ,
       )
    );

    $curl = curl_init() ;

    curl_setopt( $curl , CURLOPT_URL , 'https://api.instagram.com/oauth/access_token' ) ;
    curl_setopt( $curl , CURLOPT_HEADER, true ) ; 
    curl_setopt( $curl , CURLOPT_CUSTOMREQUEST , 'POST' ) ; 
    curl_setopt( $curl , CURLOPT_RETURNTRANSFER , true ) ;          
    curl_setopt( $curl , CURLOPT_POSTFIELDS , $body ) ;
    curl_setopt( $curl , CURLOPT_TIMEOUT , 5 ) ;	

    $response1 = curl_exec( $curl ) ;
    $response2 = curl_getinfo( $curl ) ;	

    curl_close( $curl ) ;
    $json = substr( $response1, $response2['header_size'] ) ;
    $obj = json_decode( $json ) ;
    
    if( !$obj || !isset($obj->user->id) || !isset($obj->user->username) || !isset($obj->user->profile_picture) || !isset($obj->access_token) ){
      echo <<< EOM
      <p>エラーです！</p>
EOM;
    }else{
      $token = $obj->access_token;
      echo <<< EOM
      <p>アクセストークンは<br/><span style="font-weight:bold;">{$token}</span><br/>です！</p>
EOM;
    }

    $_SESSION = array() ;
    session_destroy() ;
  }
}
```