Laravel social login
Bài đăng này đã không được cập nhật trong 3 năm
- Ở thời điểm viết bài mình sử dụng phiên bản
Laravel 5.4
để thực hiện chức năngSocial login
cụ thể là Laravel 5.4 facebook login, các tài khoảng twitter, google, github,.. các bạn làm tương tự, mình sẽ nói ngắn gọi ở trong bài.
1. Vấn đề
Input:
- Thực hiện chức năng đăng nhập bằng email (cái này Laravel đã hỗ trợ sẵn nên mình bỏ qua) và cho phép đăng nhập bằng facebook.
Output:
- Tạo được tài khoản đăng nhập vào ứng dụng Laravel với tài khoản facebook.
2. Giải pháp
- Database:
- Bảng
users
với các trườngname
,email
,.. - Bảng
social_accounts
với các trườnguser_id
,provider_user_id
,provider
,...
- Bảng
- Ý tưởng: Ta sẽ tạo ra link cho phép người dùng click vào để login bằng tài khoản facebook, khi người dùng click vào nút này ta sẽ get thông tin của người dùng từ tài khoản facebook và insert vào database rồi thực hiện login. Ở đây laravel đã cung cấp sẵn cho ta package Socialite để giải quyết vẫn đề này.
- Thực hiện:
-
Cài đặt package socialite bằng composer
composer require laravel/socialite
-
Thêm providers vào file
config/app.php
'providers' => [ // Other service providers... Laravel\Socialite\SocialiteServiceProvider::class, ],
-
Thêm alias
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
-
Tiếp theo ta cần có một app facebook, bạn vào link này để tạo một app: https://developers.facebook.com/
-
Ta chọn Add a new app để tạo một app mới cho ứng dụng của ta, mình đã tạo sẵn app
laravel54
với config như sau: -
Ta lưu
App ID
,App Secret
để tý thêm vào file config của ứng dụng và ta phải nhớ pubblic app này nhé: -
OK phần app facebook, ta sẽ quay lại với ứng dụng laravel.
-
Đầu tiên ta cần thêm vào file
config/services.php
'facebook' => [ 'client_id' => env('FACEBOOK_APP_ID'), 'client_secret' => env('FACEBOOK_APP_SECRET'), 'redirect' => env('FACEBOOK_APP_CALLBACK_URL'), ], 'github' => [ 'client_id' => env('GITHUB_APP_ID'), 'client_secret' => env('GITHUB_APP_SECRET'), 'redirect' => env('GITHUB_APP_CALLBACK_URL'), ], 'twitter' => [ 'client_id' => env('TWITTER_APP_ID'), 'client_secret' => env('TWITTER_APP_SECRET'), 'redirect' => env('TWITTER_APP_CALLBACK_URL'), ], 'google' => [ 'client_id' => env('GOOGLE_APP_ID'), 'client_secret' => env('GOOGLE_APP_SECRET'), 'redirect' => env('GOOGLE_APP_CALLBACK_URL'), ],
-
Nếu chỉ cần login bằng facebook thì ta chỉ cần thêm config services cho tài khoản facebook thôi, ở đây mình muốn nói đối với các tài khoản khác cũng tương tự. Các config này ta sẽ thêm sau vào file
.env
. -
Tiếp theo ta tạo controller
SocialAuthController
php artisan make:controller SocialAuthController
-
Thêm 2 method
redirect
vàcallback
namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Services\SocialAccountService; use Illuminate\Support\Facades\Log; use Socialite; class SocialAuthController extends Controller { public function redirect($social) { return Socialite::driver($social)->redirect(); } public function callback($social) { $user = SocialAccountService::createOrGetUser(Socialite::driver($social)->user(), $social); auth()->login($user); return redirect()->to('/home'); } }
-
Service
SocialAccountService
để xử lý tạo mới user hoặc get user từ database, file này mình để trong thư mụcapp\Services
:namespace App\Services; use Laravel\Socialite\Contracts\User as ProviderUser; use App\SocialAccount; use App\User; class SocialAccountService { public static function createOrGetUser(ProviderUser $providerUser, $social) { $account = SocialAccount::whereProvider($social) ->whereProviderUserId($providerUser->getId()) ->first(); if ($account) { return $account->user; } else { $email = $providerUser->getEmail() ?? $providerUser->getNickname(); $account = new SocialAccount([ 'provider_user_id' => $providerUser->getId(), 'provider' => $social ]); $user = User::whereEmail($email)->first(); if (!$user) { $user = User::create([ 'email' => $email, 'name' => $providerUser->getName(), 'password' => $providerUser->getName(), ]); } $account->user()->associate($user); $account->save(); return $user; } } }
-
Đoạn
getEmail()
mình check nếu không get được thì sẽ set email bằng nickName do tài khoản twitter mà để private email thì ta sẽ không get được email, trường hợp này bạn có thể bắt người dùng update email rồi mới cho login cũng rất đơn giản. Hoặc ta sẽ set thêm cho bảng user trường email có thể null như sau:$table->string('email')->unique()->nullable();
-
Tất nhiên là ta phải nhớ thêm bảng
social_accounts
và model cho nó:php artisan make:migration create_social_accounts_table --create="social_accounts" php artisan make:model SocialAccount
-
Thêm vào file migrate
Schema::create('social_accounts', function (Blueprint $table) { $table->integer('user_id'); $table->string('provider_user_id'); $table->string('provider'); $table->timestamps(); });
-
Thêm quan hệ và model
SocialAccount
namespace App; use Illuminate\Database\Eloquent\Model; class SocialAccount extends Model { protected $fillable = ['user_id', 'provider_user_id', 'provider']; public function user() { return $this->belongsTo('App\User'); } }
-
Thêm vào
routes/web.php
Route::get('/redirect/{social}', 'SocialAuthController@redirect'); Route::get('/callback/{social}', 'SocialAuthController@callback');
-
Method
redirect
sẽ điều hướng người dùng đến facebook để xác nhận và methodcallback
để xử lý gọi lại từ facebook. -
Đến đây ta sẽ update file
.env
như sau:FACEBOOK_APP_ID = 642423652634577 FACEBOOK_APP_SECRET = 91ffb713415e5e11f2a9f464a48c83b3 FACEBOOK_APP_CALLBACK_URL = http://localhost:8000/callback/facebook
-
Twitter, google, github ta cũng làm tương tự, nếu bạn muốn test thử thì có thể dùng luôn key của app mình đã tạo sẵn:
GITHUB_APP_ID = 79f02d69b8205fe2282b GITHUB_APP_SECRET = c82b3d193f3bf22b590d13ce47bd1e9da148026c GITHUB_APP_CALLBACK_URL = http://localhost:8000/callback/github TWITTER_APP_ID = 9C83R9zQ2TOIEFW5k9hUbKks2 TWITTER_APP_SECRET = DS5Si26a486MaqmBERsIcwJrjxVSYETm10KCeUhz5Tog6xBuyQ TWITTER_APP_CALLBACK_URL = http://localhost:8000/callback/twitter GOOGLE_APP_ID = 762749737436-vjblilaa7ijs906c3c9f5vgj7v3t78ks.apps.googleusercontent.com GOOGLE_APP_SECRET = 5drmbvkdCIXqOelFlMHaiExi GOOGLE_APP_CALLBACK_URL = http://localhost:8000/callback/google
-
Cuối cùng ta chỉ cần thêm link cho nút login bằng facebook và trải nghiệm thôi, chẳng hạn thêm
<a href="redirect/facebook">FB Login</a>
vào trangwelcome.blade.php
như mình chẳng hạn.
-
Tài liệu tham khảo Laravel 5.3 Social and Email Multi-Authentication
All rights reserved