Skip to content

Instantly share code, notes, and snippets.

@chihiro-adachi
Created July 31, 2017 09:07
Show Gist options
  • Save chihiro-adachi/e6a23bd34ad4674c4d32c10ff2068e49 to your computer and use it in GitHub Desktop.
Save chihiro-adachi/e6a23bd34ad4674c4d32c10ff2068e49 to your computer and use it in GitHub Desktop.
authorization code grant のサンプル(open id connect版)
<?php
require_once __DIR__.'/vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
/**
* authorization code grant のサンプル(open id connect版)
*
* 登場人物一覧
* - rp: http://localhost:8082 (このスクリプト)
* - idp: http://localhost:8081 (APIプラグインをインストールしたEC-CUBE)
* - resource server: http://localhost:8081 (同上)
*
* 参考
* - https://www.slideshare.net/kura_lab/openid-connect-id
*
* 実装
* - done: authorization request
* - done: authorization code
* - done: token request
* - todo: resouece access
*
*/
define('CLIENT_ID', 'eb11d480a5c8dcb7a61a7af76f41a3e6e4137c2d');
define('CLIENT_SECRET', 'f32675bbb8665325a5260eeff59ac19e27f9c7ce');
define('REDIRECT_URL', 'http://localhost:8082/auth-code-grant-openid.php');
define('URL_AUTHORIZE', 'http://localhost:8081/index_dev.php/admin/OAuth2/v0/authorize');
define('URL_ACCESS_TOKEN', 'http://localhost:8081/index_dev.php/OAuth2/v0/token');
define('URL_ENDPOINT_PRODUCT', '');
$request = Request::createFromGlobals();
$session = new Session();
$session->start();
// エラー時はdescription出力して終了.
if ($request->query->has('error')) {
echo 'error:'.$request->query->get('error_description');
exit;
}
// authorization codeがない場合は, 認可サーバにリクエストする(リダイレクト).
if (false === $request->query->has('code')) {
// state, nonceを生成. とりあえずuniqidで.
$state = uniqid('s');
$nonce = uniqid('n');
// 認可エンドポイントへのurlの構築
$url = URL_AUTHORIZE
.'?response_type=code'
.'&client_id='.CLIENT_ID
.'&redirect_uri='.rawurlencode(REDIRECT_URL)
.'&scope='.rawurlencode('openid email product_read') // openidは必須
.'&state='.$state // csrf対策
.'&nonce='.$nonce; // リプレイアタック対策
// state, nonceをセッションに保持.
$session->set('state', $state);
$session->set('nonce', $nonce);
// 認可サーバにリダイレクト
header('Location: '.$url);
exit;
// 認可サーバへリダイレクト後、同意を得たら認可コードが返却される
} else {
$state = $request->query->get('state');
$stateInSession = $session->get('state');
// stateのチェック
if (is_null($state) || $state !== $stateInSession) {
echo 'error: state is invalid.';
exit;
}
// アクセストークンの取得
// basic認証が必要なケースもあるがここでは省略.
$client = new \GuzzleHttp\Client(
[
'base_url' => 'http://localhost:8081/index_dev.php/',
]
);
$headers = ['Content-Type' => 'application/x-www-form-urlencoded'];
$body = 'grant_type=authorization_code'
.'&code='.$request->query->get('code')
.'&redirect_uri='.rawurlencode(REDIRECT_URL)
// http://doc.ec-cube.net/api_authorization のサンプルではclientidとsecuretも必要. state, nonceは必要?なくても動く
.'&client_id='.CLIENT_ID
.'&client_secret='.CLIENT_SECRET
// .'&state='.$state
// .'&nonce='.$nonce;
;
$response = $client->request(
'POST',
URL_ACCESS_TOKEN,
[
'headers' => $headers,
'body' => $body,
]
);
$body = (string)$response->getBody();
var_dump($body);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment