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

laravel-socialite (1)

امروزه در اکثر سایت ها امکانی فراهم است که کاربران می توانند توسط حساب های شبکه های اجتماعی مختلفی که دارند، مثل حساب فیسبوک، توئیتر و... عمل ثبت نام در سایت را انجام دهند.

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

لاراول از نسخه 5.2 به بعد یک ماژول احراز هویت معرفی کرد.

برای استفاده از این قابلیت کافی است که از دستور php artisan make:auth استفاده کنیم. با اجرای این دستور لاراول کنترلر و ویوهای مورد نظر را برای شما به طور خودکار ایجاد می کند، سپس یک فولدر به نام auth در فولدر Views ایجاد می شود و درون فولدر auth چند ویو با نام های Register، login، password reset و .. ایجاد می شودو

همچنین در پوشه Controllers یک پوشه به نام auth تولید و داخل آن دو کنترلر به نام های AuthController و passwordController ایجاد می گردد. همچنین در فولدر routes  روت های مربوط به این دو کنترلر به طور خودکار ساخته می شوند.

برای شروع کار یک پروژه لاراول ایجاد می کنیم.

composer create-project laravel/laravel lara-social

راه اندازی پایگاه داده لاراول

در این مرحله، باید پیکربندی های مربوط به پایگاه داده را در لاراول انجام دهیم. برای اینکار نیاز به دانستن نام هاست، نام کاربری و نام پایگاه داده دارید. در این آموزش پسورد را خالی می گذارم.

برای شروع فایل .env که مربوط به پیکربندی های محیطی لاراول است و در روت پروژه قرار دارد را باز کنید و کدهای زیر را در آن قرار دهید. (در قسمت username نام کاربری پایگاه داده خودتان را قرار دهید)

DB_HOST=localhost
DB_DATABASE=lara-social
DB_USERNAME=username
DB_PASSWORD=

ساخت جدول کاربران در پایگاه داده

اگر فولدر database/migration را نگاه کنید می بینید که لاراول قبلاً دو migration برای ساخت جدول users و جدول password reset ایجاد کرده است. Migration مربوط به جدول users را باز کنید. اما قبل از تغییر این فایل چند نکته هست که باید به آن توجه داشته باشید.

کاربری که توسط OAuth ساخته می شود، یک ارائه دهنده (provider) دارد و باید مقدار provider_id را یک مقدار منحصر به فرد قرار دهیم.

دوستان عزیز چنانچه درباره OAuth اطلاعات ندارید لطفا مقاله زیر را مطالعه کنید:

هنگام استفاده از توئیتر، گاهی کاربران هیچ ایمیلی وارد نمی کنند و در نتیجه مقدار hashیی که توسط کالبک به سرور ارسال می شود، هیچ ایمیلی ندارد، که این می تواند باعث بروز خطا شود.

برای رفع این مسئله باید مقدار فیلد email در جدول پایگاه داده را nullable قرار دهیم. همچنین هنگامی که توسط OAuth یک کاربر در پایگاه داده ایجاد می کنیم، هیچ کلمه عبوری به پایگاه داده ارسال نمی کنیم، پس باید فیلد password هم nullable باشد.

پس در این مرحله باید چهار کار را انجام دهیم: فیلدهای provider و provider_id را به جدول user اضافه میکنیم و فیلد provider_id را unique قرار می دهیم.

همچنین فیلدهای email و password را nullable می گذاریم.

فایل database/migration/{timestamp}_create_users_table.php را باز کنید و کدهای زیر را در متد up() قرار دهید.

database/migrations/{titmestamp}\create_users_table.php_

[...]
public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->nullable();
            $table->string('password', 60)->nullable();
            $table->string('provider');
            $table->string('provider_id');
            $table->rememberToken();
            $table->timestamps();
        });
    }
[...]

اگر قبلاً با لاراول آشنایی داشته باشید می دانید که برای افزودن فیلد یا ستون های جدید به یک جدول باید یک migration جدید ایجاد کرد و سپس فیلدهای مورد نظر را به آن اضافه کرد.

دستور زیر باعث ساخته شدن جدول در پایگاه داده می شود.

php artisan migrate

این دستور باعث ساخته شدن دو جدول users و password reset می شود.

مدل User

فایل app/User.php را باز کرده و فیلدهای provider و provider_id را به پروپرتی $fillable اضافه کنید.

[...]
protected $fillable = [
        'name', 'email', 'password', 'provider', 'provider_id'
    ];
[...]

سپس با دستور زیر قابلیت احراز هویت را به برنامه مان اضافه می کنیم.

php artisan make:auth

حال اگر دستور php artisan serve را اجرا کنید، پروژه در مرورگر اجرا خواهد شد و همان طور که می بینید قسمت های sign up  و sign in به نوار منو اضافه شده است.

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

این پکیج تمام قابلیت هایی که برای ثبت نام و لاگین کاربران توسط شبکه های اجتماعی نیاز دارید را ارائه می دهد.

اضافه کردن Socialite به پروژه

برای شروع کار، ابتدا باید پکیج Socialite را نصب کنیم.

composer require laravel/socialite

بعد از نصب این پکیج، باید Laravel/Socialite/SocialiteServiceProvider را در فایل config/app.php ثبت کنید.

config/app.php

'providers' => [
    // Other service providers...

    Laravel\Socialite\SocialiteServiceProvider::class,
],

پس فایل config/app.php را باز کنید و در آرایه aliases، facade مربوط به Socialite را اضافه کنید.

config/app.php

'aliases' => [
    // Other aliases...

    'Socialite' => Laravel\Socialite\Facades\Socialite::class,
],

ثبت نام کاربران

در قدم بعد باید مشخصات سرویس های OAuth را به برنامه اضافه کنیم.

این مشخصات باید در فایل پیکربندی config/Services.php نوشته شوند.

برای شروع، ابتدا یک برنامه جدید در سایت توئیتر ثبت می کنیم تا بتوانیم client id و secret id را دریافت کنیم.

همچنین باید یک Callback url برای برنامه مان تنظیم کنیم. برای ثبت نام برنامه جدید در توئیتر به این آدرس مراجعه کنید.

دقت داشته باشید قبلاً به توئیتر لاگین کرده باشید.

در قسمت callback url آدرس http://localhost:8000/oauth/twitter/callback را قرار دهید. هنگامی که برنامه تان ساخته شد، برای دریافت consumer API Key و consumer API Secret روی تب Keys and access tokens کلیک کنید.

سپس فایل config/services.php را باز کنید و توئیتر را به عنوان یک سرویس به آن اضافه کنید.

config/services.php

[...]
'twitter' => [
        'client_id'     => env('TWITTER_ID'),
        'client_secret' => env('TWITTER_SECRET'),
        'redirect'      => env('TWITTER_URL'),
    ],
[...]

سپس کلیدهایی که پس از ثبت برنامه تان در توئیتر دریافت کردید را مطابق زیر در فایل .env وارد کنید.

TWITTER_ID={{API Key}}
TWITTER_SECRET={{API secret}}
TWITTER_URL={{callbackurl}}

برای فیسبوک و گیت هاب هم این فرآیند را تکرار می کنیم.

برای فیسبوک برنامه تان را در اینجا ثبت کنید، سپس روی Settings در نوار منو کلیک کنید.

بعد از اینکه پنجره Settings باز شد، می توانید به API Key و API Secret تان دسترسی داشته باشید.

در قدم بعد روی platform  کلیک کنید و در قسمت website آدرس وب سایتی که برنامه لاراولی تان روی آن اجرا می شود را وارد کنید. در این مثال، آدرس http://localhost:8000 را وارد می کنیم. سپس App Domain را برابر localhost قرار داده و روی save  کلیک می کنیم.

سپس باید فیسبوک را به عنوان یک سرویس به فایل config/services.php اضافه کنیم.

دقت داشته باشید که حتما باید مقادیر key secret و callback url را در فایل .env قرار دهید. در این مثال باید مقدار FACEBOOK_URL را برابر http://localhost:8000/oauth/facebook/callback/config/services.php قرار دهیم.

[...]
'facebook' => [
        'client_id'     => env('FACEBOOK_ID'),
        'client_secret' => env('FACEBOOK_SECRET'),
        'redirect'      => env('FACEBOOK_URL'),
    ],
[...]

برای ساخت یک برنامه جدید در گیت هاب روی این لینک کلیک کنید. جزئیات مربوط به برنامه تان را وارد کنید. سپس API Key  و API Secret تان را دریافت کنید.

سپس فایل config/services.php را باز کرده و گیت هاب را به عنوان یک سرویس به آن اضافه کنید.

مسیریابی

در مرحله بعد شما می توانید کاربران را احراز هویت کنید برای اینکار به دو روت نیاز داریم: یک روت برای هدایت کاربر به ارائه دهنده OAuth و دیگری برای دریافت کالبک از ارائه دهنده (Provider) بعد از انجام احراز هویت، استفاده می شود.

App/Http/routes.php

// Other routes
[...]
// OAuth Routes
Route::get('auth/{provider}', 'Auth\AuthController@redirectToProvider');
Route::get('auth/{provider}/callback', 'Auth\AuthController@handleProviderCallback');

کنترلر Auth

باید با استفاده از فساد facade Socialite به پکیج Socialite دسترسی داشته باشیم.

همچنین برای دسترسی به متدهای مختلف Auth باید از facade Auth استفاده کنیم.

app/Http/Controllers/Auth/AuthController.php

[...]
use Auth;
use Socialite;
[...]


class AuthController extends Controller
{
    // Some methods which were generated with the app
    [...]
    /**
     **_ Redirect the user to the OAuth Provider.
     _**
     **_ @return Response
     _**/
    public function redirectToProvider($provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    /**
     _ Obtain the user information from provider.  Check if the user already exists in our
     _ database by looking up their provider_id in the database.
     _ If the user exists, log them in. Otherwise, create a new user then log them in. After that 
     _ redirect them to the authenticated users homepage.
     _
     _ @return Response
     _/
    public function handleProviderCallback($provider)
    {
        $user = Socialite::driver($provider)->user();

        $authUser = $this->findOrCreateUser($user, $provider);
        Auth::login($authUser, true);
        return redirect($this->redirectTo);
    }

    /**
     _ If a user has registered before using social auth, return the user
     _ else, create a new user object.
     _ @param  $user Socialite user object
     _ @param $provider Social auth provider
     _ @return  User
     */
    public function findOrCreateUser($user, $provider)
    {
        $authUser = User::where('provider_id', $user->id)->first();
        if ($authUser) {
            return $authUser;
        }
        return User::create([
            'name'     => $user->name,
            'email'    => $user->email,
            'provider' => $provider,
            'provider_id' => $user->id
        ]);
    }
    [...]

متد redirectToProvider برای ارسال کاربر به ارائه دهنده OAuth استفاده می شود و متد handleProviderCallback درخواست های ورودی را خوانده و اطلاعات مربوط به کاربران را از ارائه دهنده (provider)ها بازیابی می کند.

همچنین متد findOrCreate یک کاربر را در پایگاه داده جستجو می کند و اگر وجود داشت آن را در قالب یک آبجکت user بر می گرداند. در غیراینصورت یک کاربر جدید ساخته می شود. این کار از ثبت نام مجدد یک کاربرجلوگیری می کند.

لینک های ورود به سایت با شبکه های اجتماعی

حال باید لینک هایی برای ثبت نام و لاگین کاربران توسط فیسبوک، توئیتر و گیت هاب ایجاد کنیم. این لینک ها به آدرس /auth/{provider} اشاره می کنند و کاربران را برای احراز هویت به ارائه دهنده OAuth هدایت می کند.

در ویو مربوط به ثبت نام کاربران کد زیر را بعد از دکمه Register اضافه کنید.

Resources/Views/Auth/register.blade.php

[...]
<form class="form-horizontal" role="form" method="POST" action="{{ url('/register') }}">
<!--Other form fields above the button-->
    <div class="form-group">
        <div class="col-md-6 col-md-offset-4">
            <button type="submit" class="btn btn-primary">
            <i class="fa fa-btn fa-user"></i> Register
            </button>
        </div>
    </div>
    <hr>
    <div class="form-group">
        <div class="col-md-6 col-md-offset-4">
            <a href="{{ url('/auth/github') }}" class="btn btn-github"><i class="fa fa-github"></i> Github</a>
            <a href="{{ url('/auth/twitter') }}" class="btn btn-twitter"><i class="fa fa-twitter"></i> Twitter</a>
            <a href="{{ url('/auth/facebook') }}" class="btn btn-facebook"><i class="fa fa-facebook"></i> Facebook</a>
        </div>
    </div>
</form>
[...]

ویو مربوط به ثبت نام کاربران باید مطابق زیر باشد:

ثبت نام کاربران در لاارول

در ویو لاگین کدهای زیر را بعد از دکمه Login  اضافه کنید.

Resources/Views/Auth/login.blade.php

[...]
<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}">
<!--Other form fields above the button-->
    <div class="form-group">
        <div class="col-md-6 col-md-offset-4">
            <button type="submit" class="btn btn-primary">
            <i class="fa fa-btn fa-sign-in"></i> Login
            </button>
        </div>
    </div>
    <hr>
    <div class="form-group">
        <div class="col-md-6 col-md-offset-4">
            <a href="{{ url('/auth/github') }}" class="btn btn-github"><i class="fa fa-github"></i> Github</a>
            <a href="{{ url('/auth/twitter') }}" class="btn btn-twitter"><i class="fa fa-twitter"></i> Twitter</a>
            <a href="{{ url('/auth/facebook') }}" class="btn btn-facebook"><i class="fa fa-facebook"></i> Facebook</a>
        </div>
    </div>
</form>
[...]

به این ترتیب کاربران می توانند توسط حساب های شبکه اجتماعی خود، در سایت شما ثبت نام و یا لاگین کنند.

پکیج Socialite محدود به فیسبوک، توئیتر و گیت هاب نیست. این پکیج از LinkedIn، Google و Bitbucket هم پشتیبانی می کند.

امیدوارم این آموزش برای شما مفید واقع شده باشد.

نویسنده شوید

دیدگاه‌های شما (5 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

mb
26 اردیبهشت 1399
سلام دلیل این خطا Authorization Error Error 400: invalid_requestوقتی میخام لاگین کنم

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

mb
26 اردیبهشت 1399
سلام دلیل خطا چیه Authorization Error Error 400: invalid_request

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محسن بابائی
12 مهر 1398
سلام لطفا در صورت امکان پست رو اپدیت کنید فریمورک 6 تغییراتی در این زمینه داشته ممنون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

حسین
13 بهمن 1397
سلام callback url مربوط به سایت گیت هاب رو میخواستم لطفا در اختیارم قرار بدین. در این پستتون هیچ اشاره ای بهش نکردین.میخوام با اکانت گیت هاب وارد سایتم بشم. ممنونم

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

حسین
13 بهمن 1397
سلام عالی بود من مدتها دنبال چنین اموزش خوبی بودم. متشکرم

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.