이 튜토리얼은 Envato Tuts+의 "PHP로 스타트업 구축" 시리즈의 일부입니다. 이 시리즈에서는 Meeting Planner 앱을 실제 사례로 사용하여 스타트업을 시작하는 과정을 컨셉부터 현실까지 안내해 드리겠습니다. 모든 단계에서 귀하가 배울 수 있는 오픈 소스 예제로 Meeting Planner 코드를 공개하겠습니다. 스타트업과 관련해 발생하는 비즈니스 이슈도 다루겠습니다.
이 튜토리얼에서는 등록과 재사용을 더 쉽고 효율적으로 만들기 위해 OAuth를 일반적인 소셜 네트워크와 통합하는 방법을 안내하겠습니다. 저는 Meeting Planner의 타겟 청중에게 가장 적합하다고 생각되는 네트워크인 Facebook, Google, Twitter 및 LinkedIn을 탐색할 것입니다.
Meeting Planner의 모든 코드는 PHP의 Yii2 프레임워크를 사용하여 작성되었습니다. Yii2에 대해 자세히 알아보려면 Envato Tuts+에서 Yii2를 사용한 프로그래밍 시리즈 병렬 시리즈를 확인하세요.
아직 미팅 플래너를 사용해보지 않으셨다면 오늘 첫 번째 미팅을 예약해 보세요. 올해는 정말 함께하기 시작했습니다. 결국 Yii2에 내장된 AuthClient 지원을 사용하여 위의 모든 네트워크에서 로그인을 제공할 수 있었습니다. 따라서 즉시 이러한 네트워크를 사용하여 등록할 수 있습니다.
피드백을 환영합니다. 질문이나 주제 제안이 있으면 아래에 의견을 남겨주세요. Twitter @reifman을 통해 저에게 연락하실 수도 있습니다.
AuthClient는 OpenID, OAuth 또는 OAuth2를 사용하여 애플리케이션이 타사 서비스에 인증할 수 있도록 Yii에 내장된 지원입니다.
2015년 6월 내 Yii2 시리즈를 팔로우했다면 제가 OpenID를 통해 Google과 통합하기 위해 AuthClient를 사용하는 것을 보셨을 것입니다. 하지만 회사는 곧 해당 사양에 대한 지원을 종료했습니다. 그런 다음 12월에 Yii2-User 확장을 사용하여 Google OAuth 지원을 추가하는 튜토리얼을 작성했습니다. Yii2 프레임워크에는 아직 없는 기능입니다. 그러나 Yii2-User는 이미 사용자용 코드 베이스가 있는 기존 코드 베이스와 잘 통합되지 않습니다. 하지만 운 좋게도 Yii2 프레임워크에 Google OAuth에 대한 지원이 추가되어 모든 것이 더 쉬워졌습니다.
이 튜토리얼에서는 새로운 AuthClient 기능을 사용하여 다양한 인기 소셜 네트워크와 통합하는 방법을 안내하겠습니다. 기본적으로 Yii는 다음 클라이언트에 대한 지원을 제공합니다:
소셜 네트워크를 통해 Meeting Planner 연결을 지원하는 또 다른 동기는 사람들이 나타나 자신의 이름과 이메일을 쉽게 공유할 수 있다는 것입니다. 이메일과 비밀번호를 통해 가입하면 실제로는 그 사람의 이름을 알 수 없습니다. 그러나 다른 소셜 네트워크와 달리 Twitter는 사용자 이메일 주소를 얻는 데 심각한 장벽을 만들어 결국 일시적으로 비활성화하게 만들었습니다.
코드 통합을 시작하겠습니다.
먼저 OAuth용 Yii 구성요소, 즉 Yii의 AuthClient를 설치해야 합니다.
composer.json에 AuthClient 라이브러리를 추가해 보겠습니다.
으아아아그런 다음 Composer를 업데이트해야 합니다.
으아아아그리고 frontendconfigmain.php
의 구성 파일에 AuthClient 구성 설정을 추가해야 합니다.
지원하려는 모든 타사 서비스에 대한 배열 요소를 추가하세요(각 서비스에 대한 세부 정보는 AuthClient 가이드에서 확인할 수 있습니다):
으아아아이러한 모든 키와 비밀에 대한 코드를 얻으려면 각 소셜 네트워크에 앱을 등록해야 합니다. 이는 일반적으로 시간이 많이 소요됩니다.
일부 네트워크 등록과 다른 네트워크의 일부 심층 구성을 안내하는 저를 따라오세요.
트위터 앱 대시보드에서 새 트위터 앱 만들기:
클릭 Create New App - 콜백 URL이 불필요하다고 생각했는데 이제는 자리 표시자 http://mydomain.com/user/security/auth를 사용합니다.
이것은 우리 앱의 새로운 페이지입니다:
이것은 Settings 페이지입니다:
이 페이지는 키 및 액세스 토큰 페이지입니다. 여기서는 Consumer Key(API Key) 및 Consumer Secret(API 비밀) 을 복사해야 합니다.
这些密钥位于我们的 mp.ini 文件中,该文件被读入 $config
变量上面为 Twitter 配置 AuthClient。
接下来,让我们访问 Facebook 开发者控制台并添加新应用:
我们现在选择创建一个WWW网站应用:
提供我们的应用程序名称:
并收集我们的新应用 ID:
他们要求提供所有常规信息,例如网址:
然后您可以在列表中找到我们的Meeting Planner应用程序:
以下是您的应用程序的 Facebook 仪表板:
Google API 比 Twitter 和 Facebook 稍微复杂一些,因此用户体验有点难以遵循。但基本上,一旦您创建了应用程序,您就需要 OAuth 2.0 密钥,您可以通过在凭据屏幕上打开应用程序区域来获取该密钥:
这将带您到这里:
出于安全原因,Google(和 LinkedIn)需要完整列表,详细说明在执行过程中可能会使用哪些 URL 路径和参数。 OAuth 序列。在开发过程中,这可能需要大量调整 - 即使是从本地主机进行测试也是如此。
输入后,您将看到下面列出的内容:
Google 在帮助您配置同意屏幕方面做得很好,您的用户在尝试注册或链接时将看到该屏幕他们的 Google 帐户与会议策划者的关系:
与 Google 相比,LinkedIn 相当简单。您需要申请的基本详细信息:
与 Google 一样,它们需要您在开发和生产中使用的所有网址。您还可以在此页面获取密钥:
在从 GitHub 中保护您的密钥中,我详细描述了如何使用配置文件来存储除 GitHub 存储库之外的所有密钥。然后,我将此文件包含在 Yii 配置文件的开头。这可以防止我意外地将我的密钥签入我的存储库并危及我的帐户。
我们将 Twitter 和 Facebook 应用程序密钥和机密放入存储库外部的 /var/secure/mp.ini
中:
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
中的代码,其中包含这些设置并设置各个配置变量:
<?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
表,该表将存储社交服务、该人的 ID 以及会议规划器中该人员的 user_id
:
./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'? (yes|no) [no]:yes New migration created successfully.
迁移如下所示:
<?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.' NOT NULL', 'source' => Schema::TYPE_STRING.' NOT NULL', 'source_id' => Schema::TYPE_STRING.' NOT NULL', ], $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}}'); } }
这是我们运行时的结果:
./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? (yes|no) [no]:yes *** 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 表将包含如下内容:
Yii2 的 AuthChoice 小部件在为您配置的每个服务实现登录按钮方面做得非常出色。它按照您设置服务和密钥数组的顺序执行此操作(以便您可以更改它)。
将小部件添加到我们的表单(login.php 和 signup.php)非常简单:
<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 -->
现在这是我们的注册页面:
对于已登录的现有用户,我为他们创建了一种简单的方法来关联其帐户。它在个人资料设置页面上称为关联社交帐户:
如果您点击LinkedIn,这是他们的 OAuth 屏幕,要求您授予会议策划者权限:
这是 Google 的屏幕:
但是当用户允许我们分享他们的社交帐户详细信息时,到底发生了什么?让我们看一下我编写的用于处理用户操作的代码。
\frontend\controllers\SiteController.php
处理传入的 auth
操作到函数 onAuthSuccess
:
/** * @inheritdoc */ public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], 'captcha' => [ 'class' => 'yii\captcha\CaptchaAction', 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, ], 'auth' => [ 'class' => 'yii\authclient\AuthAction', 'successCallback' => [$this, 'onAuthSuccess'], ], ]; }
大多数优秀的 OAuth 客户端都会在类似的属性数组中提供类似的信息,Twitter 除外。 Twitter 在共享电子邮件地址方面起步较晚,对于我的 MVP 来说,现在不值得进行额外的工作来配置它。 Google 和 Facebook 更为流行。
首先,我正在收集服务详细信息并收集尽可能多的个人数据:电子邮件、名字和姓氏、全名,尤其是该社交网络中该用户的外部 ID:
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.' '.$lastname; 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
表中搜索此人的外部 ID。如果它们不存在,则它们对于 Meeting Planner 来说是新的。如果它们存在,我们就会认出它们。
同样,我们需要检查他们的电子邮件地址是否已存在,因为该电子邮件地址的人可能之前已在 Meeting Planner 中注册过。
当 MeetingPlanner.io 当前没有经过身份验证的用户时,下面的代码将查看传入的用户数据。
如果外部 ID 已在我们的 Auth 表中,我们会将其登录。这对他们来说很简单!
如果我们无法识别该 ID,但我们已经注册了电子邮件地址,我们会要求他们通过用户名和密码登录,然后关联他们的帐户。
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']); }
接下来,如果他们在点击社交帐户按钮后进入登录页面,并且我们无法识别外部 ID或电子邮件地址,我们将他们重定向到注册页面并要求他们从注册页面重试。
如果他们从注册页面进行链接,我们将确保新用户不会面临(先前存在的 Meeting Planner 用户的)重复用户名的风险。在这种情况下,我们暂时用随机字符串扩展用户名。我们使用密码将他们注册为 Meeting Planner 的新用户(他们实际上并不需要密码)。
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
模式。)
} 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 信息中填写命名信息——还没有完成):
Google, Facebook, LinkedIn과 같은 주요 서비스에 대한 OAuth 연결 설정의 영향이 꽤 크다는 점을 인정해야 합니다. Meeting Planner에 가입하고 정기적으로 사용하면 매우 쉽고 향후 인증 속도가 빨라집니다. 이건 정말 좀 믿기지 않는 일이다.
미팅 플래너들이 지난 몇 달 동안 정말 뭉쳤습니다. 지금 바로 소셜 로그인 및 회원가입을 해보세요! PHP로 스타트업 구축 시리즈에서 곧 출시될 튜토리얼을 확인하세요. 제품이 MVP로 전환됨에 따라 많은 흥미로운 기능이 제공될 것입니다.
저도 SEC의 새로운 크라우드 펀딩 규정 시행에 맞춰 WeFunder를 사용해보기 시작했습니다. 우리 프로필을 따르는 것을 고려해 보십시오. 아마 우리 시리즈의 일부로 이것에 대해 더 많이 이야기할 것입니다.
아래에 질문과 의견을 자유롭게 추가하세요. 저는 일반적으로 토론에 참여합니다. Twitter @reifman을 통해 저에게 연락하실 수도 있습니다. 기능 및 테마 요청을 환영합니다.
다음 Yii2 튜토리얼이 언제 공개되는지 알고 싶으시면 Twitter @reifman에서 저를 팔로우하시거나 제 강사 페이지를 확인하세요. 내 강사 페이지에는 이 시리즈의 모든 기사가 즉시 포함됩니다.
위 내용은 PHP 및 OAuth로 스타트업 온보딩 단순화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!