
Это руководство является частью серии « Создай свой стартап с помощью PHP» на Envato Tuts +. В этой серии я проведу вас через запуск стартапа от концепции до реальности, используя мое приложение Meeting Planner в качестве примера из реальной жизни. На каждом этапе я буду публиковать код Планировщика собраний в качестве примеров с открытым исходным кодом, из которых вы можете извлечь уроки. Я также буду решать вопросы, связанные с бизнесом по мере их возникновения
В этом руководстве я расскажу вам, как реализовать интеграцию OAuth с общими социальными сетями, чтобы упростить и повысить эффективность регистрации и повторного использования. Я исследую Facebook, Google, Twitter и LinkedIn, сети, которые я считаю наиболее подходящими для целевых пользователей Meeting Planner.
Весь код для Meeting Planner написан на Yii2 Framework для PHP. Если вы хотите узнать больше о Yii2, ознакомьтесь с нашей параллельной серией Программирование с Yii2 на Envato Tuts +.
Если вы еще не опробовали Планировщик собраний, попробуйте назначить первую встречу прямо сейчас . Это действительно начинает собираться вместе в этом году. В конечном итоге я смог использовать встроенную поддержку Yii2 AuthClient для входа в систему из всех вышеперечисленных сетей — так что вы можете использовать их для регистрации прямо сейчас.
Обратная связь приветствуется. Если у вас есть вопрос или предложение по теме, пожалуйста, оставьте комментарий ниже. Вы также можете связаться со мной в Twitter @reifman .
Что такое AuthClient?
AuthClient — это встроенная поддержка Yii для ваших приложений для аутентификации через сторонние сервисы с OpenID , OAuth или OAuth2 .
Если бы вы следили за моей серией Yii2 в июне 2015 года, вы бы увидели, что я использую AuthClient для интеграции с Google через OpenID , но вскоре компания прекратила поддержку спецификации. Затем, в декабре, я написал учебник, в котором использовалось расширение Yii2-User для добавления поддержки Google OAuth — в Yii2 Framework этого еще не было. Тем не менее, Yii2-User плохо интегрируется с установленными базами кода, которые уже имеют ориентированную на пользователя базу кода. Но, к счастью, с тех пор в Yii2 Framework появилась поддержка Google OAuth, и все стало более простым.
В этом руководстве я познакомлю вас с использованием новой функциональности AuthClient для интеграции с различными популярными социальными сетями. Yii обеспечивает поддержку следующих клиентов:
Еще одной мотивацией для поддержки подключения к Meeting Planner через социальные сети является то, что он позволяет людям появляться и легко делиться своим именем и электронной почтой с нами. С электронной почтой и паролем мы фактически никогда не узнаем их имя. Тем не менее, Twitter, в отличие от других социальных сетей, создает значительные проблемные барьеры для получения адресов электронной почты пользователей, что в конечном итоге привело меня к его отключению на данный момент.
Давайте начнем с интеграции кода.
Установка AuthClient в нашем приложении
Во-первых, нам нужно установить компоненты Yii для OAuth, AuthClient Yii.
Добавить AuthClient в Composer
Давайте добавим библиотеку AuthClient в composer.json:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
«minimum-stability»: «stable»,
«require»: {
«php»: «>=5.4.0»,
«yiisoft/yii2»: «*»,
«yiisoft/yii2-bootstrap»: «*»,
«yiisoft/yii2-swiftmailer»: «*»,
«2amigos/yii2-google-maps-library»: «*»,
«2amigos/yii2-google-places-library»: «*»,
«stichoza/google-translate-php»: «~2.0»,
«2amigos/yii2-date-time-picker-widget»: «*»,
«yiisoft/yii2-jui»: «*»,
«cebe/yii2-gravatar»: «*»,
«kartik-v/yii2-widget-fileinput»: «*»,
«kartik-v/yii2-widget-switchinput»: «*»,
«yiisoft/yii2-imagine»: «*»,
«2amigos/yii2-resource-manager-component»: «0.1.*»,
«yiisoft/yii2-authclient»: «~2.0.0»
},
|
Затем нам нужно обновить composer:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
sudo composer update
Password:
Loading composer repositories with package information
Updating dependencies (including require-dev)
— Updating 2amigos/yii2-date-time-picker-widget (0.1.0 => 0.1.1)
Checking out 572e2448ba1cd207b339dd5d117e3d1d23f0bbc3
— Installing yiisoft/yii2-authclient (2.0.2)
Loading from cache
Writing lock file
Generating autoload files
|
Настройка поддержки AuthClient
И нам нужно добавить параметры конфигурации AuthClient в наш файл конфигурации в \frontend\config\main.php .
Добавьте элементы массива для всех сторонних сервисов, которые вы хотите поддерживать (подробности для каждого можно найти в Руководстве AuthClient ):
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
‘components’ => [
‘authClientCollection’ => [
‘class’ => ‘yii\authclient\Collection’,
‘clients’ => [
‘facebook’ => [
‘class’ => ‘yii\authclient\clients\Facebook’,
‘clientId’ => $config[‘oauth_fb_id’],
‘clientSecret’ => $config[‘oauth_fb_secret’],
],
‘google’ => [
‘class’ => ‘yii\authclient\clients\GoogleOAuth’,
‘clientId’ => $config[‘oauth_google_client_id’],
‘clientSecret’ => $config[‘oauth_google_client_secret’],
],
‘linkedin’ => [
‘class’ => ‘yii\authclient\clients\LinkedIn’,
‘clientId’ => $config[‘linkedin_client_id’],
‘clientSecret’ => $config[‘linkedin_client_secret’],
],
‘twitter’ => [
‘class’ => ‘yii\authclient\clients\Twitter’,
‘consumerKey’ => $config[‘oauth_twitter_key’],
‘consumerSecret’ => $config[‘oauth_twitter_secret’],
],
],
],
|
Чтобы получить коды для всех этих ключей и секретов, вам необходимо зарегистрировать свое приложение в каждой социальной сети. Это часто может занимать много времени.
Регистрация приложений для разработчиков
Следуйте инструкциям, как я проведу вас через регистрацию в некоторых сетях, а некоторые — в более глубоких аспектах конфигурации — в других.
Регистрация через Twitter
Создайте новое приложение Twitter на панели инструментов приложения Twitter :

Нажмите « Создать новое приложение» — я обнаружил, что URL-адрес обратного вызова не нужен, но сейчас я использовал заполнитель http://mydomain.com/user/security/auth .

Вот новая страница для нашего приложения:

Вот страница настроек :

Вот страница Ключи и токены доступа . Здесь нам нужно скопировать Consumer Key (API Key) и Consumer Secret (API Secret) :

Эти ключи находятся в нашем файле mp.ini, который читается в переменную $config выше для настройки AuthClient для Twitter.
Зарегистрируйте наше приложение Facebook
Далее, давайте посетим консоль разработчика Facebook и добавим новое приложение :

Сейчас мы выберем создание веб- приложения WWW :

Укажите название нашего приложения:

И соберите наш новый идентификатор приложения :

Они запрашивают всю обычную информацию, такую как URL:

И тогда вы можете найти наше приложение Meeting Planner в списке:

Вот панель инструментов Facebook для вашего приложения:

Зарегистрируйтесь в Google
Google API-интерфейсы немного сложнее, чем Twitter и Facebook, поэтому следовать UX немного сложнее. Но в основном, когда вы создаете приложение, вам нужны ключи OAuth 2.0, которые вы получаете, открывая область приложения на экране учетных данных:

Это берет вас здесь:

По соображениям безопасности Google (и LinkedIn) требуется полный список того, какие именно URL-пути и параметры могут использоваться во время последовательности OAuth. В процессе разработки это может потребовать значительных корректировок — даже для тестирования с локального хоста.
Как только вы введете их, вы увидите их в списке ниже:

Google отлично помогает вам настроить экран согласия, который увидят ваши пользователи, когда они попытаются зарегистрироваться или связать свою учетную запись Google с Планировщиком собраний:

Зарегистрируйтесь в LinkedIn
LinkedIn довольно прост по сравнению с Google. Вам требуются основные детали для вашего приложения:

Как и Google, им требуются все URL, которые вы будете использовать при разработке и производстве. Вы также можете получить ключи на этой странице:

Размещение ключей в нашем конфигурационном файле
В разделе Защита ваших ключей от GitHub я подробно описал, как я использую файл конфигурации для хранения всех моих ключей, кроме моего репозитория GitHub. Затем я включаю этот файл в начало моих файлов конфигурации Yii. Это удерживает меня от случайной проверки моих ключей к моему хранилищу и взлома моих учетных записей.
Мы /var/secure/mp.ini ключи и секреты приложения Twitter и Facebook в /var/secure/mp.ini вне репозитория:
|
01
02
03
04
05
06
07
08
09
10
|
oauth_fb_id=»154xxxxxxxxxxxxxx33″
oauth_fb_secret=»bcxxxxxxxxxxxxxxdda»
oauth_twitter_key =»JCpxxxxxxxxxxxxxxnsF»
oauth_twitter_secret=»f3xxxxxxxxxxxxxxxxxxxxxxxxxxxxu37″
oauth_twitter_token=»153xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxfBj»
oauth_twitter_token_secret=»Synxxxxxxxxxxxxxxxxxxxxxxxxxxxx4X»
oauth_google_client_id = «1xxxxxxxxxxxxxxxxxxxxxxq.apps.googleusercontent.com»
oauth_google_client_secret = «cfkxxxxxxxxxxxxxxox»
linkedin_client_id = «7xxxxxxxxxxxxxxq»
linkedin_client_secret =»IxxxxxxxxxxxxxxI»
|
Здесь снова приведен код в \frontend\config\main.php который включает эти параметры и устанавливает отдельные переменные конфигурации:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<?php
$config = parse_ini_file(‘/var/secure/mp.ini’, true);
$params = array_merge(
require(__DIR__ . ‘/../../common/config/params.php’),
require(__DIR__ . ‘/../../common/config/params-local.php’),
require(__DIR__ . ‘/params.php’),
require(__DIR__ . ‘/params-local.php’)
);
return [
‘id’ => ‘app-frontend’,
‘basePath’ => dirname(__DIR__),
‘bootstrap’ => [‘log’],
‘controllerNamespace’ => ‘frontend\controllers’,
‘components’ => [
‘authClientCollection’ => [
‘class’ => ‘yii\authclient\Collection’,
‘clients’ => [
‘google’ => [
‘class’ => ‘yii\authclient\clients\GoogleOpenId’
],
‘facebook’ => [
‘class’ => ‘yii\authclient\clients\Facebook’,
‘clientId’ => $config[‘oauth_fb_id’],
‘clientSecret’ => $config[‘oauth_fb_secret’],
],
‘twitter’ => [
‘class’ => ‘yii\authclient\clients\Twitter’,
‘consumerKey’ => $config[‘oauth_twitter_key’],
‘consumerSecret’ => $config[‘oauth_twitter_secret’],
],
],
],
‘urlManager’ => [
|
Обновление схемы для хранения ключей сеанса
Теперь, когда мы готовы написать код для интеграции регистрации в социальной сети и входа в систему, нам нужна база данных для создания таблицы Auth которой будет храниться социальная служба, ее идентификатор для этого человека и user_id для этого человека в Meeting Planner:
|
1
2
3
4
5
|
./yii migrate/create create_auth_table
Yii Migration Tool (based on Yii v2.0.2)
Create new migration ‘/Users/Jeff/Sites/mp/console/migrations/m150227_235635_create_auth_table.php’?
New migration created successfully.
|
Вот как выглядит миграция:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?php
use yii\db\Schema;
use yii\db\Migration;
class m150227_235635_create_auth_table extends Migration
{
public function up()
{
$tableOptions = null;
if ($this->db->driverName === ‘mysql’) {
$tableOptions = ‘CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB’;
}
$this->createTable(‘{{%auth}}’, [
‘id’ => Schema::TYPE_PK,
‘user_id’ => Schema::TYPE_BIGINT.’
‘source’ => Schema::TYPE_STRING.’
‘source_id’ => Schema::TYPE_STRING.’
], $tableOptions);
$this->addForeignKey(‘fk-auth-user_id-user-id’, ‘{{%auth}}’, ‘user_id’, ‘{{%user}}’, ‘id’, ‘CASCADE’, ‘CASCADE’);
}
public function down()
{
$this->dropForeignKey(‘fk-auth-user_id-user-id’, ‘{{%auth}}’);
$this->dropTable(‘{{%auth}}’);
}
}
|
Вот результат, когда мы запускаем его:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
./yii migrate/up
Yii Migration Tool (based on Yii v2.0.2)
Total 1 new migration to be applied:
m150227_235635_create_auth_table
Apply the above migration?
*** applying m150227_235635_create_auth_table
> create table {{%auth}} … done (time: 0.016s)
> add foreign key fk-auth-user_id-user-id: {{%auth}} (user_id) references {{%user}} (id) … done (time: 0.012s)
*** applied m150227_235635_create_auth_table (time: 0.033s)
Migrated up successfully.
|
Еще раз, я использовал генератор кода Yii Gii для создания модели Auth:

В конечном итоге таблица Auth будет содержать содержимое, подобное этому:

Добавьте виджет AuthChoice в Планировщик собраний
Виджет Yh2 AuthChoice отлично справляется с реализацией кнопок входа в систему для каждой настраиваемой вами службы. И это происходит в том порядке, в котором вы устанавливаете массив сервисов и ключей (чтобы вы могли его изменить).
Довольно просто добавить виджет в наши формы по адресу login.php и signup.php:
|
1
2
3
4
5
6
7
8
9
|
<div class=»row»>
<div class=»col-lg-5″>
<p>Or, login with one of the following services:</p>
<?= yii\authclient\widgets\AuthChoice::widget([
‘baseAuthUrl’ => [‘site/auth’,’mode’=>’login’],
‘popupMode’ => false,
]) ?>
</div> <!— end col-lg-5 —>
</div> <!— end row —>
|
Вот наша страница регистрации сейчас:

Для существующих пользователей, которые вошли в систему, я создал для них простой способ связать свою учетную запись. Это называется Link Social Accounts на странице настроек профиля:

Если вы нажмете LinkedIn , Вот их экран OAuth, который попросит вас дать разрешение на Планировщик собраний:

А вот экран для Google:

Но что на самом деле происходит, когда пользователь позволяет нам делиться информацией о своем социальном аккаунте? Давайте пройдемся по коду, который я написал для обработки действий пользователей.
Обработка разрешения OAuth
\frontend\controllers\SiteController.php обрабатывает входящее действие auth для функции onAuthSuccess :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
/**
* @inheritdoc
*/
public function actions()
{
return [
‘error’ => [
‘class’ => ‘yii\web\ErrorAction’,
],
‘captcha’ => [
‘class’ => ‘yii\captcha\CaptchaAction’,
‘fixedVerifyCode’ => YII_ENV_TEST ?
],
‘auth’ => [
‘class’ => ‘yii\authclient\AuthAction’,
‘successCallback’ => [$this, ‘onAuthSuccess’],
],
];
}
|
Большинство хороших клиентов OAuth предоставляют аналогичную информацию в аналогичном массиве свойств, кроме Twitter. Твиттер опоздал на игру по обмену адресами электронной почты, и для моего MVP сейчас не стоит дополнительной работы по его настройке. Google и Facebook намного более распространены.
Во-первых, я собираю информацию об услуге и собираю как можно больше личных данных: электронную почту, имя и фамилию, полное имя и особенно внешний идентификатор этого пользователя в этой социальной сети:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public function onAuthSuccess($client)
{
$mode = Yii::$app->getRequest()->getQueryParam(‘mode’);
$attributes = $client->getUserAttributes();
$serviceId = $attributes[‘id’];
$serviceProvider = $client->getId();
$serviceTitle = $client->getTitle();
$firstname =»;
$lastname=»;
$fullname =»;
switch ($serviceProvider) {
case ‘facebook’:
$username = $email = $attributes[’email’];
$fullname = $attributes[‘name’];
break;
case ‘google’:
$email = $attributes[’emails’][0][‘value’];
if (isset($attributes[‘displayName’])) {
$fullname = $username = $attributes[‘displayName’];
}
if (isset($attributes[‘name’][‘familyName’]) and isset($attributes[‘name’][‘givenName’])) {
$lastname = $attributes[‘name’][‘familyName’];
$firstname = $attributes[‘name’][‘givenName’];
}
break;
case ‘linkedin’:
$username = $email = $attributes[’email-address’];
$lastname = $attributes[‘first-name’];
$firstname = $attributes[‘last-name’];
$fullname = $firstname.’
break;
case ‘twitter’:
$username = $attributes[‘screen_name’];
$fullname = $attributes[‘name’];
// to do — fix social helpers
$email = $serviceId.’@twitter.com’;
break;
}
// to do — split names into first and last with parser
$auth = Auth::find()->where([
‘source’ => (string)$serviceProvider,
‘source_id’ => (string)$serviceId,
])->one();
|
В последних строках кода выше мы ищем в таблице Auth внешний идентификатор человека. Если они не существуют, они являются новичками в Meeting Planner. Если они существуют, то мы их узнаем.
Точно так же нам нужно проверить, существует ли их адрес электронной почты, потому что возможно человек с таким адресом электронной почты, ранее зарегистрированный в Meeting Planner.
Если в MeetingPlanner.io нет текущего аутентифицированного пользователя, приведенный ниже код просматривает входящие данные пользователя.
Если внешний идентификатор уже есть в нашей таблице аутентификации, мы регистрируем их. Это было легко (для них)!
Если мы не узнаем идентификатор, но уже зарегистрировали адрес электронной почты, мы просим их войти в систему с помощью имени пользователя и пароля, а затем связать свою учетную запись.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
if (Yii::$app->user->isGuest) {
if ($auth) {
// if the user_id associated with this oauth login is registered, try to log them in
$user_id = $auth->user_id;
$person = new \common\models\User;
$identity = $person->findIdentity($user_id);
Yii::$app->user->login($identity);
} else {
// it’s a new oauth id
// first check if we know the email address
if (isset($email) && User::find()->where([’email’ => $email])->exists()) {
// the email is already registered, ask person to link accounts after logging in
Yii::$app->getSession()->setFlash(‘error’, [
Yii::t(‘frontend’, «The email in this {client} account is already registered. Please login using your username and password first, then link to this account in your profile settings.», [‘client’ => $serviceTitle]),
]);
$this->redirect([‘login’]);
} else {
if ($mode == ‘login’) {
// they were trying to login with an unconnected account — ask them to login normally and link after
Yii::$app->getSession()->setFlash(‘error’, [
Yii::t(‘frontend’, «We don’t recognize the user with this email from {client}. If you wish to sign up, try again below. If you wish to link {client} to your Meeting Planner account, login first with your username and password. Then visit your profile settings.», [‘client’ => $serviceTitle]),
]);
$this->redirect([‘signup’]);
}
|

Затем, если они начали на странице входа в систему, когда нажали кнопку учетной записи в социальной сети, и мы не распознали внешний идентификатор или адрес электронной почты, мы перенаправим их на страницу регистрации и попросим повторить попытку — со страницы регистрации.
Если они ссылались на странице регистрации Мы гарантируем, что новый пользователь не рискует дублировать имя пользователя (ранее существовавшего пользователя Планировщика собраний). В этом сценарии мы просто расширяем имя пользователя случайной строкой. И мы регистрируем их как нового пользователя в Meeting Planner с паролем (который им на самом деле не нужен).
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
else if ($mode == ‘signup’) {
// sign up a new account using oauth
// look for username that exists already and differentiate it
if (isset($username) && User::find()->where([‘username’ => $username])->exists()) {
$username.=Yii::$app->security->generateRandomString(6);
}
$password = Yii::$app->security->generateRandomString(12);
$user = new User([
‘username’ => $username, // $attributes[‘login’],
’email’ => $email,
‘password’ => $password,
‘status’ => User::STATUS_ACTIVE,
]);
$user->generateAuthKey();
$user->generatePasswordResetToken();
$transaction = $user->getDb()->beginTransaction();
if ($user->save()) {
$auth = new Auth([
‘user_id’ => $user->id,
‘source’ => $serviceProvider, // $client->getId(),
‘source_id’ => $serviceId, // (string)$attributes[‘id’],
]);
if ($auth->save()) {
$transaction->commit();
Yii::$app->user->login($user);
} else {
print_r($auth->getErrors());
}
} else {
print_r($user->getErrors());
}
} // end signup
}
}
|
На последнем шаге, описанном выше, мы добавляем данные их внешнего социального аккаунта в Auth стол для будущего признания.
Связывание существующих учетных записей Планировщика собраний
Если они поступают со вкладки «Ссылка на социальные учетные записи» на странице профиля пользователя (а не на странице входа в систему или регистрации), нам просто нужно добавить данные своей внешней учетной записи в Auth и переместите свой логин в User::STATUS_ACTIVE . (Помните, что пользователи, которые приходят по ссылкам приглашения в Планировщике собраний, но никогда не регистрируются, имеют режим User::STATUS_PASSIVE .)
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
} else {
// user already logged in, link the accounts
if (!$auth) { // add auth provider
$auth = new Auth([
‘user_id’ => Yii::$app->user->id,
‘source’ => $serviceProvider,
‘source_id’ => $serviceId,
]);
$auth->validate();
$auth->save();
$u = User::findOne(Yii::$app->user->id);
$u->status = User::STATUS_ACTIVE;
$u->update();
Yii::$app->session->setFlash(‘success’, Yii::t(‘frontend’, ‘Your {serviceProvider} account has been connected to your Meeting Planner account. In the future you can log in with a single click of its logo.’,
array(‘serviceProvider’=>$serviceTitle)));
}
}
|
Вот как это выглядит (в будущем я буду заполнять информацию об именах из информации OAuth — это еще не сделано):

В заключение
Я должен признать, что влияние рабочих соединений OAuth на основные сервисы, такие как Google, Facebook и LinkedIn, довольно драматично. Это упрощает регистрацию и регулярное использование Meeting Planner и ускоряет аутентификацию в будущем. Это действительно невероятно.
Встреча Планировщик действительно собрались последние пару месяцев. Пожалуйста, попробуйте социальный логин и регистрацию прямо сейчас! Следите за будущими уроками в нашей серии «Построение стартапа с помощью PHP» — в процессе продвижения к MVP появится множество интересных функций.
Я также начинаю экспериментировать с WeFunder, основываясь на внедрении новых правил краудфандинга SEC . Пожалуйста, обратите внимание на наш профиль . Я могу написать об этом больше как часть нашей серии.
Пожалуйста, не стесняйтесь добавлять свои вопросы и комментарии ниже; Я обычно участвую в обсуждениях. Вы также можете связаться со мной в Twitter @reifman . Я приветствую тематические и тематические запросы.
Если вы хотите узнать, когда появится следующий учебник по Yii2, следуйте за мной @reifman в Твиттере или зайдите на страницу моего инструктора . Моя страница инструктора будет включать все статьи из этой серии, как только они будут опубликованы.