こんにちは!
とびろぐ管理人のとびうおです。
今回、Laravel8にapple idログインを実装したので、そちらについて解説をしていきたいと思います!
とても大変でした…。
必要なものの準備
まず、apple idログインに必要なものは、
- client_id
- redirect_uri
- 秘密鍵
の3つです。
なお、apple developerからこれらは取得します。
apple developerからの取得方法
↑のサイトにアクセスをします。
こちらのidentifilersというのをクリックします。
続いて、右側のApple IDsというのを押して、Service IDsというのをくりっくしましょう!
ここの一番右側だよ!
もし、serviceを作っていない場合は、➕ボタンから作成してみましょう!
続いて、作成できたら、作成されたものをクリックすると以下のような画面になります。
ここで、クリックをして、configuerを書きましょう。
ここにリダイレクトをするドメインとかcallback urlとかを記述しましょう!
その次に、また、Identifiersに戻って、作成をして、その中にある
にクリックをつけましょう。
そして、最後にkeyを作るよ!
続いて最後にkeyを作ります。
こちらのページより、Keysにアクセスをして、➕マークでkeyを作ります。
こちらにチェックをいれて、
先ほど作ったIdentifiersを右側の選択できるとこから、選択しましょう!
そして、「p8」ファイルをダウンロードしてください。このファイルは一度しかダウンロードできないので気をつけてください!
続いて、コードを書いていく。
では、実際にLaravelのコードを書いていきます。
なお、この実装では、セキュア実装よりもわかりやすさを重視していますので、本番運用される場合は必ずリファクタを実行してください。
※Laravelの基本はわかっているものとします!
動いた!を目指すよ!
redirectする関数
ではまず、Apple IDの画面にリダイレクトできるような関数を作成してきます。
public function redirectToApple()
{
$client_id ='#Identifiersを指定';
$redirect_uri = '#call back urlを指定';
$state = bin2hex(random_bytes(16)); // CSRF対策用のランダムな文字列
$url = "https://appleid.apple.com/auth/authorize?" . http_build_query([
'response_type' => 'code',
'response_mode' => 'form_post',
'client_id' => $client_id,
'redirect_uri' => $redirect_uri,
'state' => $state,
'scope' => 'name email',
]);
//↓ csrf対策用のDBなので消してもOKです。
AppleOauthState::query()->create(['state' => $state]);
return redirect($url);
}
$client_id =’#Identifiersを指定’;
と
$redirect_uri = ‘#call back urlを指定’;
こちらの2つを書き換えてください!
※scrf実装はしなくても良いです。
これで、まずはこのcontrollerからappleのログイン画面に飛ぶことを確認しましょう!
リダイレクトして戻ってくる画面
続いて、リダイレクトしてくるところのcontrollerを作成してきます。
最終的にemailがechoされるかと思います!
public function handleAppleCallback(Request $request)
{
//↓ csrf対策用のDBなので消してもOKです。
$stateExists = AppleOauthState::query()->where('state', $request->state)->exists();
if (!$stateExists) {
return redirect()->route('top'); // 失敗時のリダイレクト先を適切に設定
}
$code = $request->input('code');
$client = new Client();
$response = $client->post('https://appleid.apple.com/auth/token', [
'form_params' => [
'client_id' =>'#Identifiersを指定';
'client_secret' => $this->generateClientSecret(),
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' =>'#call back urlを指定';
],
]);
$tokenResponse = json_decode((string) $response->getBody(), true);
$idToken = $tokenResponse['id_token'];
// トークンからkidを取得するためにヘッダーをデコードします。
$tks = explode('.', $idToken);
if (count($tks) < 3) {
throw new UnexpectedValueException('Wrong number of segments');
}
list($headb64, $bodyb64, $cryptob64) = $tks;
$header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64));
$kid = $header->kid;
$keys = json_decode(file_get_contents('https://appleid.apple.com/auth/keys'), true);
$key = JWK::parseKeySet($keys)[$kid];
$decoded = JWT::decode($idToken, $key);
$email = $decoded->email;
return $email;
}
function generateClientSecret()
{
$keyPath = storage_path('hoge.p8'); // 秘密鍵のパス
$teamId = 'Apple Developer Team ID'; // Apple Developer Team ID
$clientId = ''; // Service ID (Apple Developer Portalで設定)
$keyId = ''; // .p8ファイルのKey ID
$privateKey = file_get_contents($keyPath);
$payload = [
'iss' => $teamId,
'iat' => time(),
'exp' => time() + 3600, // トークンの有効期限 (例: 1時間)
'aud' => 'https://appleid.apple.com',
'sub' => $clientId,
];
$clientSecret = JWT::encode($payload, $privateKey, 'ES256', $keyId);
return $clientSecret;
}
イメージとしては、リダイレクトする。
generateClientSecretでclientSecretを作成する
公開鍵によって、復元する
みたいなイメージです。
わかったこと
socilateを使って、apple idログインを実装することも可能ですが、色々な設定が難しかったので結局自作しました。
↑こちらに詳しい設定内容等が書かれていますので、そちらもぜひチェックしてみてください!
まとめ
Apple IDログインのやり方について解説しました!
想像よりは大変でしたが、理解すればまあまあ書ける内容になっているかと思います!
頑張るしかない!
その他にも
とびろぐでは色々な記事を公開しています!
特にLaravelの記事を多く公開しているのでぜひみてみてください!
コメント