Войдите в систему через Facebook, Google, Twitter и Github с помощью Laravel Socialite

  1. Создать приложение Laravel
  2. Настроить миграцию пользователей
  3. Создание приложения OAuth
  4. Github
  5. facebook
  6. щебет
  7. Google
  8. Настройка маршрутов для социальной аутентификации
  9. SocialAuthController
  10. Создать социальный вид
  11. Как это устроено?
  12. Аутентификация без сохранения состояния
  13. Используйте access_token для вызовов API
  14. Доступ к хранилищу пользователей Github

В настоящее время большинство веб-приложений делегируют аутентификацию другим провайдерам, таким как Facebook, Google, Twitter, Github и многим другим. Используя OAuth, нам не нужно беспокоиться о сохранении учетных данных пользователя на нашем сервере, что дает пользователю гибкость в использовании одной и той же учетной записи для авторизации на нескольких платформах.

Socialite от laravel упрощает добавление нескольких провайдеров для аутентификации. В этом посте мы создадим систему аутентификации поверх аутентификации Laravel по умолчанию для поддержки входа и регистрации через Facebook, Google, Twitter и Github.

Исходный код

Создать приложение Laravel

Создайте новое приложение laravel, я использую Laravel 5.4, как только это будет сделано, потяните светский свет, используя

композитор требует Laravel / Socialite

Теперь добавьте это в массив провайдеров и псевдонимов в файле config / app.php.

'provider' => [... Laravel \ Socialite \ SocialiteServiceProvider :: class,] .... .... 'aliases' => [.... 'Socialite' => Laravel \ Socialite \ Фасады \ Socialite :: class,]

Настроить миграцию пользователей

Теперь давайте добавим некоторые поля в миграцию нашего пользователя, предоставленные laravel, для хранения информации об аватарах и поставщиках вместе с access_token.

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

После этого запустите php artisan migrate и откройте модель app / User.php, чтобы добавить эти поля в свойство fillable, чтобы мы могли массово назначить их позже.

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

Создание приложения OAuth

Вам также нужно будет добавить учетные данные для служб OAuth, которые использует ваше приложение. Откройте файл конфигурации config / services.php, и вы должны использовать ключ facebook, twitter, linkedin, google, github или bitbucket, в зависимости от поставщиков, которых требует ваше приложение. Например, если вы используете GitHub, это будет так

'github' => ['client_id' => env ('GH_ID'), 'client_secret' => env ('GH_SECRET'), 'redirect' => env ('APP_URL'). '/ oauth / github / callback',],

А в вашем .env файле храните фактический client_id и секретно для каждого провайдера.

GH_ID = ваш-github-app-id GH_SECRET = ваш-github-app-secret

Вы можете получить учетные данные, посетив следующие разделы для разработчиков, чтобы настроить всех поставщиков услуг.

Убедитесь, что в файле .env установлено APP_URL = http: // localhost: 8000, и оно должно соответствовать URL перенаправления провайдеров. Позже в производстве вы можете изменить это на свой фактический URL приложения.

Посетите раздел разработчиков веб-сайта провайдеров и создайте приложения для разработчиков, затем заполните нижеприведенную информацию для каждого провайдера в config / services.php.

Github

https://github.com/settings/developers

'github' => ['client_id' => env ('GH_ID'), 'client_secret' => env ('GH_SECRET'), 'redirect' => env ('APP_URL'). '/ oauth / github / callback',]

facebook

https://developers.facebook.com

'facebook' => ['client_id' => env ('FB_ID'), 'client_secret' => env ('FB_SECRET'), 'redirect' => env ('APP_URL'). '/ oauth / facebook / callback',]

щебет

https://apps.twitter.com

'twitter' => ['client_id' => env ('TW_ID'), 'client_secret' => env ('TW_SECRET'), 'redirect' => env ('APP_URL'). '/ oauth / twitter / callback',],

Google

https://console.developers.google.com

'google' => ['client_id' => env ('GL_ID'), 'client_secret' => env ('GL_SECRET'), 'redirect' => env ('APP_URL'). '/ oauth / google / callback',],

Для начала просто добавьте Github : если вы можете сделать один рабочий отдых, это будет очень просто, вам просто нужны client_id и secret для всех провайдеров, которых вы хотите поддерживать в файле конфигурации config / services.php.

Настройка маршрутов для социальной аутентификации

Нам понадобятся три маршрута, один для отображения списка кнопок для провайдеров, другой для перенаправления на провайдера для аутентификации и последний для обработки обратного вызова от провайдера после авторизации.

// Social Auth Route :: get ('auth / social', 'Auth \ SocialAuthController @ show') -> name ('social.login'); Route :: get ('oauth / {driver}', 'Auth \ SocialAuthController @ redirectToProvider') -> name ('social.oauth'); Route :: get ('oauth / {driver} / callback', 'Auth \ SocialAuthController @ handleProviderCallback') -> name ('social.callback');

Как видите, нам нужен SocialAuthController для соединения с маршрутами. Запустите php artisan make: controller SocialAuthController. Он даст вам контроллер в app / Http / Controllers /, просто переместите его в папку Auth и добавьте код ниже, чтобы завершить реализацию аутентификации.

SocialAuthController

Этот контроллер отвечает за отображение кнопок входа в систему и выполнение аутентификации. Если это новый пользователь, мы создадим пользователя и имя для входа, а если идентификатор электронной почты пользователя уже присутствует в базе данных, мы просто обновим информацию о поставщике.

Пространство имен App \ Http \ Controllers \ Auth; использовать приложение \ пользователь; использовать исключение; использовать App \ Http \ Controllers \ Controller; использовать Освещение \ Поддержка \ Фасады \ Auth; использовать Laravel \ Socialite \ Фасады \ Socialite; класс SocialAuthController расширяет Controller {public function __construct () {$ this-> middleware ('guest'); } / ** * Список провайдеров, сконфигурированный в config / services, действует как белый список * * @var array * / protected $ provider = ['github', 'facebook', 'google', 'twitter']; / ** * Показать страницу входа в социальную сеть * * @return \ Illuminate \ Contracts \ View \ Factory | \ Illuminate \ View \ View * / public function show () {return view ('auth.social'); } / ** * Перенаправить к провайдеру для аутентификации * * @param $ driver * @return mixed * / public function redirectToProvider ($ driver) {if (! $ This-> isProviderAllowed ($ driver)) {вернуть $ this-> sendFailedResponse ("{$ driver} в настоящее время не поддерживается"); } try {return Socialite :: driver ($ driver) -> redirect (); } catch (Exception $ e) {// Вы должны показать что-то простое сообщение об ошибке return $ this-> sendFailedResponse ($ e-> getMessage ()); }} / ** * Обработка ответа на обратный вызов перенаправления аутентификации * * @param $ driver * @return \ Illuminate \ Http \ RedirectResponse * / public function handleProviderCallback ($ driver) {try {$ user = Socialite :: driver ($ driver) -> пользователь (); } catch (Exception $ e) {return $ this-> sendFailedResponse ($ e-> getMessage ()); } // проверяем почту в возвращенном пользователе, возвращаем пустое ($ user-> email)? $ this-> sendFailedResponse («Идентификатор электронной почты не возвращен поставщиком {$ driver}.»): $ this-> loginOrCreateAccount ($ user, $ driver); } / ** * Отправка успешного ответа * * @return \ Illuminate \ Http \ RedirectResponse * / защищенная функция sendSuccessResponse () {return redirect () -> предназначенная ('home'); } / ** * Отправить неудачный ответ с сообщением msg * * @param null $ msg * @return \ Illuminate \ Http \ RedirectResponse * / защищенная функция sendFailedResponse ($ msg = null) {return redirect () -> route ('social .login ') -> withErrors ([' msg '=> $ msg?:' Невозможно войти, попробуйте войти с другим провайдером. ']); } защищенная функция loginOrCreateAccount ($ providerUser, $ driver) {// проверка уже имеет учетную запись $ user = User :: where ('email', $ providerUser-> getEmail ()) -> first (); // если пользователь уже найден if ($ user) {// обновить аватар и провайдера, которые могли изменить $ user-> update (['avatar' => $ providerUser-> avatar, 'provider' => $ driver, ' provider_id '=> $ providerUser-> id,' access_token '=> $ providerUser-> token]); } else {// создаем нового пользователя $ user = User :: create (['name' => $ providerUser-> getName (), 'email' => $ providerUser-> getEmail (), 'avatar' => $ providerUser-> getAvatar (), 'provider' => $ driver, 'provider_id' => $ providerUser-> getId (), 'access_token' => $ providerUser-> token, // пользователь может использовать сброс пароля для создания пароля 'password' => '']); } // войти в систему пользователя Auth :: login ($ user, true); return $ this-> sendSuccessResponse (); } / ** * Проверка разрешенных провайдеров и настроенных служб * * @param $ driver * @return bool * / приватная функция isProviderAllowed ($ driver) {return in_array ($ driver, $ this-> provider) && config () -> есть ( "услуга {$ водитель}."); }}

Теперь давайте создадим представление для экрана входа в систему.

Создать социальный вид

Давайте добавим все кнопки для провайдеров, которые мы планируем поддерживать в наших ресурсах / views / auth / social.blade.php.

@extends ('layouts.app') @section ('content') <div class = "container"> <div class = "row"> <div class = "col-md-4 col-md-offset-4" > @if ($ errors-> has ('msg')) <div class = "alert alert-warning"> {{$ errors-> first ('msg')}}} <button type = "button" data-dismiss = "alert" aria-label = "Close" class = "close"> <span aria-hidden = "true"> × </ span> </ button> </ div> @endif <div class = "панель панели- default "> <div class =" panel-heading text-center "> Вход в социальную сеть </ div> <div class =" panel-body "> <p class =" lead text-center "> Аутентификация с использованием вашей учетной записи в социальной сети с один из следующих провайдеров </ p> <a href="‹ кардиологическому маршруту('social.oauth','facebook')} innovative" class="btn btn-primary btn-block"> Войдите в систему с помощью Facebook </a> < a href = "{{route ('social.oauth', 'twitter')}}" class = "btn btn-info btn-block"> Войти через Twitter </a> <a href = "{{route (' social.oauth ',' google ')}} "class =" btn btn-danger btn-block "> Войти через Google </a> <a href =" {{route (' social.oauth ',' github ') }} "class =" btn btn-default btn-block "> Войти через Github </ a > <hr> <a href="‹ кардиологическому маршруту('login')} enj" class="btn btn-default btn-block"> Войти по электронной почте </a> </ div> </ div> </ div > </ div> </ div> @endsection

Как это устроено?

Когда пользователь нажимает кнопку входа, вызывается метод Github redirectToProvider (). Который заботится об отправке пользователя на экран входа провайдера OAuth.

Перед перенаправлением пользователя вы также можете добавить дополнительные « области » в запрос с помощью метода областей. Этот метод объединит все существующие области с теми, которые вы предоставляете, например, если вы хотите получить больше информации о пользователе Facebook, вы можете передать дополнительные области:

return Socialite :: driver ($ driver) -> scopes (['public_profile', 'user_friends']) -> redirect ();

Вы можете перезаписать все существующие области, используя метод setScopes:

return Socialite :: driver ('github') -> setScopes (['scope1', 'scope2']) -> redirect ();

Возвращаясь к потоку, как только пользователь аутентифицируется, провайдер сделает запрос на URL обратного вызова, который вызовет метод handleProviderCallback (). В этом Socialite :: driver ($ driver) -> user (); Метод прочитает входящий запрос и получит информацию о пользователе от провайдера.

$ providerUser = Socialite :: driver ($ driver) -> user (); // Все провайдеры будут возвращать эти поля $ providerUser-> getId (); $ ProviderUser-> getNickname (); $ ProviderUser-> GetName (); $ ProviderUser-> getEmail (); $ ProviderUser-> getAvatar (); // Дополнительные детали, относящиеся к провайдерам как массив $ providerUser-> user

Затем мы проверяем, был ли возвращен идентификатор электронной почты для пользователя провайдера, так как мы будем хранить его в нашей таблице пользователей, мы вызовем метод loginOrCreateAccount (), который просто создаст и войдет в систему пользователя, если он еще не существует, и если он уже был В настоящее время мы будем обновлять аватар и provider_id и провайдера с обновлением access_token. Нам нужен этот токен доступа для получения любой другой информации из API провайдеров.

Аутентификация без сохранения состояния

Метод без сохранения состояния может использоваться для отключения проверки состояния сеанса. Это полезно при добавлении социальной аутентификации в API:

вернуть Socialite :: driver ('google') -> stateless () -> user ();

Мы сохранили access_token для пользователя в таблице users, поэтому, если нам нужно получить информацию о пользователях в любом месте нашего приложения, вы можете получить информацию о пользователе, вызвав $ user = Socialite :: driver ('github') -> userFromToken ($ token ).

Используйте access_token для вызовов API

Чтобы получить доступ к другому ресурсу из API провайдера, вам нужно будет аутентифицировать пользователя с областью действия, она будет отличаться у каждого провайдера. Например, в github, если вы хотите получить доступ ко всем электронным письмам пользователя, вам нужно будет передать user: email scope следующим образом:

return Socialite :: driver ($ driver) -> scopes (['user: email']) -> redirect ();

Доступ к хранилищу пользователей Github

Чтобы получить доступ к хранилищу аутентифицированных пользователей, вы можете использовать HTTP-клиент Guzzle для выполнения вызовов к конечной точке, Guzzle уже установлен с Socialite в качестве зависимости, поэтому вам не нужно его извлекать.

использовать GuzzleHttp \ Client; public function getUserGithubRepos () {// текущий пользователь, вошедший в систему $ me = auth () -> user (); $ client = новый клиент (); $ response = $ client-> get ('https://api.github.com/user/repos?access_token='. $ me-> access_token, ['headers' => ['Accept' => 'application / json ',],]); return $ response-> getBody (); }

Вы можете обратиться к документации API для получения дополнительной информации о том, как получить доступ к определенным конечным точкам для поставщика, такого как Facebook, Google Plus, Twitter и т. Д.

Как всегда, вы можете найти полный исходный код для этого на github и использовать его в качестве стартового набора для вашего следующего проекта социальной аутентификации. Я надеюсь, что вы нашли это полезным, дайте мне знать в комментариях, если у вас есть что сказать.

Исходный код

связанные с

Msg '=> $ msg?
Com/user/repos?