php artisan make:auth
and everything is generated for you, from the views to the controllers and the routes. In the views folder, an auth folder will be created containing registration, login and password reset views. You will also get an auth folder generated in the controllers containing an AuthController and PasswordController. In the routes, a route mapping to these controllers will be created as well. And that is a great thing. However, this command will only make you a traditional login.
In most sites nowadays when signing up, users have the option of signing up with a social provider such as Facebook. In this tutorial, I will teach you how to add multiple social providers to a Laravel app using Socialite package. For this tutorial we will add Facebook, Github and Twitter signups. The complete code can be found on Github
Lets generate a new Laravel app. I am using Laravel 5.2 for this tutorial.
composer create-project laravel/laravel lara-social
Database Setup
Next you need to setup your database to work with Laravel - to do this, you first need to know the hostname, username and database name. I will leave my password empty for this tutorial. Edit the Laravel environment configuration file .env (in the root directory) and add the database settings:.env
DB_HOST=localhost
DB_DATABASE=lara-social
DB_USERNAME=username
DB_PASSWORD=
Migrations and Creating the users Table
If you look inside database/migrations you will notice that the generated laravel app already came with migrations for creating the users table and password resets table.Open the migration for creating the users table. There are a few things I want us to tweak before creating the users table.
A user created via OAuth will have a
provider
and we also need a provider_id
which should be unique. With Twitter, there are cases where the user
does not have an email set up and thus the hash sent back by the
callback won't have an email resulting to an error. To counter this, we
will set the email field to nullable. Also, when creating users via
Oauth we won't be passing any passwords therefore we need to set the password
field in the migration nullable. Here, we are doing four things: adding
provider
and provider_id
columns to the users table (note the provider_id
column should be set to unique). We also make the email and password fields in the users table nullable.The
up method
in your migration should now look like this: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')->unique();
$table->rememberToken();
$table->timestamps();
});
}
[...]
If you already have a Laravel app, you will have to generate a new migration to add the extra columns to the users table and also set the email and password fields to nullable
at the database level.Then run the migration with:
php artisan migrate
This will create both the users and password resets table. User Model
We should addprovider
and provider_id
to the list of mass assignable attributes in the User
model.app/User.php
[...]
protected $fillable = [
'name', 'email', 'password', 'provider', 'provider_id'
];
[...]
We can now add authentication to our app with:php artisan make:auth
So, if we run php artisan serve
and visit http://localhost:8000
you will notice sign up
and sign in
links on the nav. Users can now sign up and login to our app via
traditional Login. We want them to be able to sign up using Facebook,
Twitter and Github. With Socialite , adding this functionality is made a breeze since Socialite handles almost all of the boilerplate social authentication code.Adding Socialite
To get started with Socialite we'll first require the packagecomposer require laravel/socialite
After installing the Socialite library, register the Laravel\Socialite\SocialiteServiceProvider
in your config/app.php configuration file like this:config/app.php
'providers' => [
// Other service providers...
Laravel\Socialite\SocialiteServiceProvider::class,
],
Then add the Socialite
facade to the aliases
array in your app
configuration file:config/app.php
'aliases' => [
// Other aliases...
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
],
App registration
The next step is to add the credentials for the OAuth services the application utilizes. These credentials should be placed in your config/services.php configuration file. In this app we are going to use Twitter, Github and Facebook.Let's start by registering our app on Twitter so we can get the
client id
and secret
. We should also set the callback URL for our app. Visit this link to register your new app. Note, you have to be logged in in order to register an app on Twitter. Set the callback URL to
http://localhost:8000/auth/twitter/callback
. Once the app has been created click on the keys and access tokens
tab to get your Consumer API Key and Consumer API secret. Add Twitter as a service in your config/services.php file:config/services.php
[...]
'twitter' => [
'client_id' => env('TWITTER_ID'),
'client_secret' => env('TWITTER_SECRET'),
'redirect' => env('TWITTER_URL'),
],
[...]
Set the keys you got after registering your app in your .env
file:TWITTER_ID={{API Key}}
TWITTER_SECRET={{API secret}}
TWITTER_URL={{callbackurl}}
We will have to repeat this for both Facebook and Github. For Facebook, register your app here then click on
settings
on the sidenav.
From the basic settings you will be able to access your API Key
and API Secret
.
Also, click the Add Platform button below the settings configuration.
Select Website in the platform dialog then enter the website URL, in our
case it is http://localhost:8000
. Set the App Domains to localhost
then save the settings.Update your config/services.php file to take note of Facebook as a service. Note, the values for the
key
, secret
and callback url
should be set in your .env
file. The FACEBOOK_URL
in this case will be http://localhost:8000/auth/facebook/callback
:config/services.php
[...]
'facebook' => [
'client_id' => env('FACEBOOK_ID'),
'client_secret' => env('FACEBOOK_SECRET'),
'redirect' => env('FACEBOOK_URL'),
],
[...]
Visit this link to create a new app on Github. Enter the app details and you will receive the API key and secret. Update your config/services.php file to take note of Github, similar to how you you did it for Twitter and Facebook.Routing
Next, you are ready to authenticate users! You will need two routes: one for redirecting the user to the OAuth provider, and another for receiving the callback from the provider after authentication:app/Http/routes.php
// Other routes
[...]
// OAuth Routes
Route::get('auth/{provider}', 'Auth\AuthController@redirectToProvider');
Route::get('auth/{provider}/callback', 'Auth\AuthController@handleProviderCallback');
Auth Controller
We will access Socialite using theSocialite
facade. We will also have to require the Auth
facade so we can access various Auth
methods: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
]);
}
[...]
The redirectToProvider
method takes care of sending the user to the OAuth provider, while the handleProviderCallback
method will read the incoming request and retrieve the user's information from the provider. Notice we also have a findOrCreateUser
method which looks up the user object in the database to see if it exists. If a user exists, the existing user object
will be returned. Otherwise, a new user will be created. This prevents users from signing up twice.Social Login Links
It's time to add the links to to the registration and login views so that users can sign up and login with Facebook, Github and Twitter. You will notice that the links point to/auth/{provider}
and will take you to OAuth provider for authentication.In the user registration view add this after Register button:
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>
[...]
The registration view should now look like this:In the login view add this after Login button:
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>
[...]
The login view should now look like this:
And there you have it, users can now sign up with various social providers. Socialite is not limited to Twitter, Facebook and Github as it also supports LinkedIn, Google and Bitbucket. I hope the tutorial was helpful.
No comments:
Post a Comment