Apple login với Laravel

Giới thiệu

"Sign in with Apple" là một tính năng mới cho phép bạn đăng nhập vào các app bằng tài khoản Apple ID, nó giống với nút đăng nhập bằng Google, Facebook,... và nhiều dịch vụ, app đang dùng.

Yêu cầu

  • PHP 7.3+
  • Laravel 8.0 +
  • Socialite 5.0 +
  • Apple Developer Account

Cài đặt

1. Cài đặt package

composer require genealabs/laravel-sign-in-with-apple

Cấu hình

  1. Tới trang https://developer.apple.com/account/resources/identifiers/list/bundleId để tạo App Idvới các thông tin sau
  • Platform: iOS, tvOS, watchOS
  • Description: mô tả về app của bạn
  • Bundle Id (bắt buộc): ví dụ com.example.id. Tốt nhất nên đặt với com + tên app
  • Chọn Sign In With Apple

Như vậy chúng ta đã tạo thành công một App ID. Công việc tiếp theo sẽ là tạo Service ID. Service ID được sử dụng khi ứng dụng của bạn chạy trên nền tảng web hoặc Android. Với ứng dụng iOS, chúng ta không cần phải tạo Service ID

  1. Tới trang https://developer.apple.com/account/resources/identifiers/list/serviceId để tạo một Service ID cho app của bạn với các thông tin sau
  • Description: mô tả về service
  • Identifier: com.your-app-name.service
  • Chọn Sign In With Apple và cấu hình
    • Primary App Id: Chọn App ID bạn vừa tạo ở Bước 1
    • Web Domain: Domain cho website của bạn
    • Return URLs: URL trỏ đến phương thức callback()
    • Chọn Save
  1. Tạo Private Key cho app của bạn. Tới trang https://developer.apple.com/account/resources/authkeys/list để tạo với các thông tin.
  • Nhập Key Name
  • Chọn Sign In With Apple
  • Cấu hình App ID với Private Key
  • Chọn Register và download
  • Đổi tên file key bạn vừa download thành key.txt
  1. Tạo Client Secret
  • Cài đặt JWT GEM
sudo gem install jwt
  • Tạo file client_sectet.rb với nội dung:
require 'jwt'

key_file = 'key.txt'
team_id = '' // ID tài khoản Apple Developer
client_id = '' // Identifier của Service ID hoặc Bundle Id của App ID
key_id = '' // ID của Key vừa tạo ở bước 3

ecdsa_key = OpenSSL::PKey::EC.new IO.read key_file

headers = {
'kid' => key_id
}

claims = {
    'iss' => team_id,
    'iat' => Time.now.to_i,
    'exp' => Time.now.to_i + 86400*180,
    'aud' => 'https://appleid.apple.com',
    'sub' => client_id,
}

token = JWT.encode claims, ecdsa_key, 'ES256', headers

puts token

client_id sẽ phụ thuộc vào app. Nếu là app iOS thì client_idBundle ID ở Bước 1. Nếu app chạy trên nền tảng web hoặc Android thì client_id sẽ là Service ID

  • Lưu file và chạy command để generate ra một JWT là client secret
ruby client_secret.rb
  • Cấu hình file .env
SIGN_IN_WITH_APPLE_LOGIN="https://domain.com/apple-login"
SIGN_IN_WITH_APPLE_REDIRECT="https://domain.com/callback"
SIGN_IN_WITH_APPLE_CLIENT_ID="client_id" // client_id của bạn
SIGN_IN_WITH_APPLE_CLIENT_SECRET="" // client secret đã được generate ở bước trên

Sau khi đã cấu hình xong, chúng ta đến bước thực hiện viết controllers cho phần login.

Thực hiện

Controller

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use GeneaLabs\LaravelSocialiter\Facades\Socialiter;
use Laravel\Socialite\Facades\Socialite;

class AppleSigninController extends Controller
{
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public static function login()
    {
        try {
            return Socialite::driver('sign-in-with-apple')->stateless()
                ->scopes(["name", "email"])
                ->redirect()->getTargetUrl();
        } catch (\Exception $exception) {
            throw $exception;
        }
    }

    public function callback(Request $request)
    {
        // get abstract user object, not persisted
        $user = Socialite::driver("sign-in-with-apple")
            ->user();
       //code
    }
}

callback sẽ trả về một object $user và chúng ta có thể tùy biến.Với lần đăng nhập đầu tiên, $user sẽ trả về thêm fullname để thực hiện đăng kí tài khoản.

Tham khảo