آموزش احراز هویت با اکانت شبکه‌های اجتماعی در لاراول

آموزش احراز هویت با اکانت شبکه‌های اجتماعی در لاراول
آموزش احراز هویت با اکانت شبکه‌های اجتماعی در لاراول

در فرآیند توسعه‌ی یک نرم‌افزار تحت وب یکی از سرویس‌های ضروری، احراز هویت است. با طراحی یک سیستم ورود و عضویت که کاربر بتواند در کمترین زمان در سایت عضو شود، تجربه کاربری بهبود پیدا می‌کند. یکی از روش‌هایی که می‌توان برای احراز هویت در سایت استفاده کرد، استفاده از حساب شبکه‌های اجتماعی است. با این روش کاربر می‌تواند با کلیک روی دکمه‌ی "ورود با گوگل" بدون وارد کردن اطلاعات شخصی و تنها با یک کلیک در سایت عضو شود. در این پست با استفاده از پکیج Socialite که توسط لاراول توسعه داده شده است، پیاده‌سازی این سیستم را در فریمورک لاراول مرور می‌کنیم.

پکیج socialite چطور کار می‌کند؟

این پکیج برای اتصال به شبکه‌های اجتماعی از پروتکل Oauth استفاده می‌کند. Oauth به کاربران اجازه می‌دهد تا بدون ارائه نام کاربری و رمز عبور، فرآیند احراز هویت را کامل کرد. در حال حاضر این پکیج از سایت‌های Google, Github, Gitlab, Meta(Facebook), Twitter, Linkedin , BitBucket پشتیبانی می‌کند. پکیج Socialite برای اتصال به این سرویس‌ها به Client Id و Client Secret نیاز دارد.

Client Id و Client Secret چه هستند؟

برای استفاده از سرویس‌های Oauth در وب‌سایت‌های ذکر شده باید پس از ثبت نام در آنها، برنامه خود را ثبت کنیم. این سایت‌ها معمولا اطلاعات یکسانی را از ما دریافت می‌کنند که در ادامه‌ی این پست به یکی از آن‌ها اشاره می‌کنیم. پس از ثبت برنامه ما در این سایت، دسته‌ای از اطلاعات را به‌نام Client Credentials به ما می‌دهد که شامل Client Id و Client Secret است.

  • ClientId یک رشته خاص برای شناسایی برنامه ما توسط سرور سرویس‌دهنده است.
  •  Client Secret یک رشته‌ی شناسایی یکتاست که به صورت محرمانه توسط سرویس‌دهنده ارائه می‌شود و برای احراز هویت برنامه ما استفاده می‌شود.

مرحله‌ی اول - نصب لاراول

با استفاده از دستور زیر توسط composer یک پروژه‌ی لاراولی جدید ایجاد می‌کنیم

composer require laravel/socialite

مرحله دوم - تنظیمات دیتابیس

برای استفاده از سرویس Oauth نیاز به ۲ ستون اضافه به نام provider و provider_id داریم. به علاوه در این روش کاربران رمز عبور وارد نمی‌کنند و این ستون نیز باید nullable باشد. در سرویسی که سایت twitter ارائه می‌کند ممکن است پس از احراز هویت فیلد email خالی باشد. به همین دلیل فیلد email نیز باید nullable باشد.

ستون‌های دیگری هم بر حسب نیاز می‌توان تعریف کرد. به عنوان مثال ما از avatar برای نمایش تصویر کاربر استفاده می‌کنیم. در کل، کد مایگریشن جدول کاربران به شکل زیر خواهد بود:

// user migration file
public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique()->nullable();
        $table->string('password')->nullable();
        $table->string('avatar')->nullable();
        $table->string('provider', 20)->nullable();
        $table->string('provider_id')->nullable();
        $table->string('access_token')->nullable();
        $table->rememberToken();
        $table->timestamps();
    });
}

سپس فایل env. را ویرایش کرده و تنظیمات دیتابیس را تنظیم می‌کنیم و مایگریشن را اجرا می‌کنیم.

php artisan migrate

حال فیلدهای اضافه‌شده را به مدل User اضافه می‌کنیم:

// User.php file
...
protected $fillable = [
    'name', 'email', 'password', 'provider', 'provider_id', 'avatar',
];
...

مرحله‌ی سوم - تنظیمات

در این مرحله Client id و Client Secret که از سرویس‌های مد نظر دریافت کرده‌ایم را در فایل env. وارد می‌کنیم. redirect نیز آدرسی است که provider روی آن اطلاعات لازم را برای ما ارسال می‌کند. سپس باید در فایل config/services.php اطلاعات مربوط به provider‌ها را قرار دهیم.

// .env file
GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret
GITHUB_CLIENT_ID=your_client_id
GITHUB_CLIENT_SECRET=your_client_secret
OAUTH_CALLBACK=/callback_url
// config/services.php file
	...
    'github' => [
        'client_id' => env('GITHUB_CLIENT_ID'),
        'client_secret' => env('GITHUB_CLIENT_SECRET'),
        'redirect' => env("APP_URL").env('OAUTH_CALLBACK'),
    ],
    'google' => [
        'client_id' => env('GOOGLE_CLIENT_ID'),
        'client_secret' => env('GOOGLE_CLIENT_SECRET'),
        'redirect' => env("APP_URL").env('OAUTH_CALLBACK'),
    ],
    ...

مرحله چهارم - دریافت اطلاعات از providerها

providerهای Oauth فرآیند مشخصی را برای ثبت پروژه و ارائه خدمات دارند. ما در این قسمت مراحل دریافت api از گوگل را بررسی می‌کنیم. provider‌های دیگر نیز فرآیندی مشابه دارند.

مراحل دریافت سرویس Oauth 2.0 گوگل

  1. وارد صفحه‌ی Google Cloud Platform Console شوید.
  2. در قسمت بالای صفحه یک پروژه انتخاب یا ایجاد کنید.
  3. سایدبار سمت چپ را باز کنید روی API & Services هاور کرده و گزینه Credentials را انتخاب کنید. 
  4. روی Create Credentials کلیک کنید سپس گزینه‌ی Oauth Client Id را انتخاب کنید.
  5. فیلد Application Type را انتخاب کنید و گزینه مورد نظر خود را انتخاب کنید. (Web Application یا Android, Ios)
  6. با انتخاب یکی از گزینه‌های قبل فیلدهای مختلفی ظاهر می‌شوند. شما در ابتدا نام پروژه خود را وارد کرده سپس از قسمت Authorized redirect URIs روی دکمه‌ی Add URI کلید کنید و لینک callback سایت خود راکه در فایل env مشخص کرده بودید وارد کنید و سپس روی Create کلیک کنید.
  7. در پنجره باز شده Client Id و Client Secret را مشاهده می‌کنید. میتوانید آنها را کپی کنید و در فایل env. جایگزین کنید.

مرحله پنجم - پیاده سازی سرویس احراز هویت

حال باید دو Route جدید تعریف کنیم. یک Route برای هدایت کردن کاربر به provider و یک Route هم برای دریافت اطلاعات از Provider‌ها و انجام عملیات احراز هویت. یک controller به نام OauthController ایجاد می‌کنیم، و در فایل web.php از آن استفاده می‌کنیم.

php artisan make:controller OauthController
// route/web.php file
use App\Http\Controllers\OauthController;
Route::get('/auth/redirect/{driver}', [OauthController::class,"redirectToProvider"])->name("oauth.redirect");
Route::get('/auth/callback/{driver}', [OauthController::class,"handleProviderCallback"])->name("oauth.callback");

در نهایت در فایل OauthController کد زیر را قرار می‌دهیم:

// OauthController file
protected $providers = [
    'github','google','twitter','linkedin'
];
public function __construct(){
    $this->middleware('guest');
}
public function redirectToProvider($driver){
    if( ! $this->isProviderAllowed($driver) ) {
        return $this->sendFailedResponse("{$driver} is not currently supported");
    }
    try {
        return Socialite::driver($driver)->redirect();
    } catch (Exception $e) {
        // You should show something simple fail message
        return $this->sendFailedResponse($e->getMessage());
    }
}
private function isProviderAllowed($driver){
    return in_array($driver, $this->providers) && config()->has("services.{$driver}");
}
public function handleProviderCallback( $driver ){
    try {
        $user = Socialite::driver($provider)->user();
        $authUser = $this->findOrCreateUser($user, $driver);
        Auth::login($authUser, true);
        return redirect()->intended('profile');
    } catch (Exception $e) {
        return $this->sendFailedResponse($e->getMessage());
    }
}
  
public function findOrCreateUser($user, $provider){
    $authUser = User::where('provider_id', $user->id)->first();
    if ($authUser) {
         $authUser->update([
            'avatar' => $user->avatar,
            'provider' => $provider,
            'provider_id' => $user->id,
            'access_token' => $user->token
         ]);
         return $authUser;
    }
    return User::create([
        'name'     => $user->name,
        'email'    => $user->email,
        'provider' => $provider,
        'provider_id' => $user->id,
        'access_token' => $providerUser->token,
        'avatar' => $providerUser->getAvatar(),
    ]);
}
protected function sendFailedResponse($msg = null)
{
    return redirect()->back()->with(['msg' => 'please try again']);
}

حال فقط کافیست در قسمت فرانت سایت لینک‌های ورود از طریق شبکه‌های اجتماعی را قرار دهیم

// blade file

<a href="{{ route("oauth.redirect",["driver"=>"github"]) }}" class="button-github">
    Login With Github
</a>
<a href="{{ route("oauth.redirect",["driver"=>"google"]) }}" class="button-google">
    Login With Google
</a>

به همین سادگی توانستیم با استفاده از پکیج Socialite، لاگین از طریق شبکه‌های اجتماعی را پیاده‌سازی کنیم و در پروژه‌های مختلف از آن استفاده کنیم. به‌عنوان نکته‌ی پایانی هم لازم است اشاره کنیم که ممکن است بعضی از این سرویس‌ها روی لوکال‌هاست کار نکنند. به عنوان مثال اگر از لینک گوگل در لوکال‌هاست استفاده کنید احتمالا با خطای SSL ERROR مواجه می‌شوید. با آپلود پروژه روی سرور و نصب SSL روی وب‌سایت خود این ارور رفع خواهد شد. اگر این مطلب برایتان مفید بود، خوشحال می‌شویم که در شبکه‌های اجتماعی بازنشر دهید.

دیدگاه‌ها

دیدگاهی ثبت نشده است

ایجاد دیدگاه

اولین نفری باشید که دیدگاه ثبت می‌کند

* ایمیل شما نمایش داده نخواهد شد

اعلانات


نظر شما با موفقیت ثبت شد. پس از تایید مدیران، در سایت نمایش داده می‌شود.

اعلانات


عملیات با موفقیت انجام شد