Construirea sistemului de pornire cu PHP Simplificarea Onramp cu OAuth

Ce veți crea

Acest tutorial face parte din programul Build Your Startup With PHP pe Envato Tuts +. În această serie, vă conduc prin lansarea unui startup de la concept la realitate, utilizând aplicația mea Planificator de întâlniri ca exemplu de viață reală. Fiecare pas de-a lungul drumului, voi lansa codul Planificatorului de Întâlniri ca exemple de sursă deschisă pe care le puteți învăța. Voi aborda, de asemenea, problemele de afaceri legate de pornire în momentul în care apar.

În acest tutorial, vă voi îndruma prin implementarea integrării OAuth cu rețele sociale comune pentru a facilita și eficientiza înregistrarea și utilizarea repetată. Voi explora Facebook, Google, Twitter și LinkedIn, rețelele pe care le văd cel mai potrivit pentru utilizatorii țintă ai Planificatorului întâlnirilor. 

Tot codul pentru Planificatorul întâlnirilor este scris în cadrul Yii2 Framework for PHP. Dacă doriți să aflați mai multe despre Yii2, consultați seria noastră paralelă Programming With Yii2 la Envato Tuts+.

Dacă nu ați încercat încă planificatorul de întâlniri, încercați să programați prima dvs. întâlnire acum. Începe să se întâlnească anul acesta. În cele din urmă, am reușit să utilizez suportul AuthClient încorporat de Yii2 pentru a vă conecta de la toate rețelele de mai sus - astfel încât să le puteți utiliza pentru a vă înregistra acum.

Feedback-ul este binevenit. Dacă aveți o sugestie de întrebare sau subiect, vă rugăm să postați un comentariu de mai jos. Puteți să mă contactați și pe Twitter @reifman.

Ce este AuthClient?

AuthClient este suportul Yii încorporat pentru ca aplicațiile dvs. să se autentifice prin intermediul unor servicii terțe cu OpenID, OAuth sau OAuth2. 

Dacă ați urmat seria Yii2 în iunie 2015, ați fi văzut-mă folosind AuthClient pentru integrarea cu Google prin intermediul OpenID, dar compania și-a încheiat sprijinul pentru caietul de sarcini la scurt timp după aceea. Apoi, în decembrie, am scris un tutorial care a folosit extensia Yii2-User pentru a adăuga suport Google OAuth - cadrul Yii2 nu a avut încă acest lucru. Cu toate acestea, Yii2-User nu se integrează bine cu baze de date stabilite care au deja o bază de date orientată spre utilizator. Din fericire, însă, cadrul Yii2 a adăugat sprijin pentru Google OAuth și totul a devenit mai simplu. 

În acest tutorial, vă voi îndruma utilizând noua funcționalitate AuthClient pentru a vă integra într-o varietate de rețele sociale populare. Din cutie, Yii oferă suport pentru următorii clienți:

  • Facebook
  • GitHub
  • Google
  • LinkedIn
  • Microsoft Live
  • Stare de nervozitate

O altă motivație pentru a sprijini conexiunea cu Planificatorul de întâlniri prin intermediul rețelelor sociale este că permite oamenilor să apară și să le împărtășească cu ușurință numele și adresa de e-mail cu noi. Cu înregistrarea prin e-mail și parolă, de fapt, nu ne învățăm numele. Cu toate acestea, Twitter, spre deosebire de alte rețele sociale, creează în mod semnificativ obstacole problematice în obținerea adreselor de e-mail ale utilizatorilor, ceea ce, în cele din urmă, ma determinat să o dezactivez pentru moment.

Să începem cu integrarea codului.

Instalarea AuthClient în aplicația noastră

În primul rând, trebuie să instalați componentele Yii pentru OAuth, AuthClientul Yii.

Adăugați AuthClient la Compozitor

Să adăugăm biblioteca AuthClient la compozitor.json:

 "minimum-stabilitate": "stabil", "solicita": "php": "> = 5.4.0" "yiisoft / yii2" yiisoft / yii2-swiftmailer ": "*", "2 amigos/yii2-google-maps-library": "*", "2 amigos/yii2-google-places-library": "*"," stichoza / google-translate- php ":" ~ 2.0 "," 2 amigos/yii2-date-time-picker-widget ":" * "," yiisoft / yii2-jui ":" * "," cebe / yii2-gravatar " "kartik-v / yii2-widget-fileinput": "*", "kartik-v / yii2-widget-switchinput": "*" -manager-component ":" 0.1. * "," yiisoft / yii2-authclient ":" ~ 2.0.0 ",

Apoi, trebuie să actualizăm compozitorul:

sudo actualizare compozitor Parola: Incarcare arhive compozitor cu pachete de informații Actualizarea dependențe (inclusiv necesită-dev) - Actualizarea 2 amigos/yii2-date-time-picker-widget (0.1.0 => 0.1.1) Verificarea 572e2448ba1cd207b339dd5d117e3d1d23f0bbc3 - Instalarea yiisoft / yii2 -authclient (2.0.2) Încărcare din cache Fișier de blocare de scriere Generarea fișierelor autoload 

Configurarea suportului AuthClient

Și, trebuie să adăugăm setările de configurare AuthClient la fișierul nostru de configurare din \ Frontend al \ config \ main.php.

Adăugați elemente de matrice pentru toate serviciile terță parte pe care doriți să le acceptați (detalii despre fiecare pot fi găsite în Ghidul AuthClient): 

'components' => ['authClientCollection' => ['class' => 'yii \ authclient \ “, 'clientId' => $ config [ 'oauth_fb_id'], 'clientSecret' => $ config [ 'oauth_fb_secret'],], 'google' => [ 'clasa' => 'Yii \ authclient \ clienti \ GoogleOAuth' , 'clientId' => $ config [ 'oauth_google_client_id'] => $ config [ 'oauth_google_client_secret'],], 'linkedin', 'clientSecret' => [ 'clasa' => 'Yii \ authclient \ clienti \ LinkedIn', 'clientId' => $ config ['linkedin_client_id'], 'clientSecret' => $ config ['linkedin_client_secret']], 'twitter' => "config ['oauth_twitter_key'], 'consumerSecret' => $ config ['oauth_twitter_secret'],],],],

Pentru a obține coduri pentru toate acele chei și secrete, trebuie să vă înregistrați cererea cu fiecare rețea socială. Acest lucru poate fi adesea consumator de timp.

Înregistrarea aplicațiilor pentru dezvoltatori

Urmăriți-vă de-a lungul timpului în care vă conduc prin conectarea cu unele dintre rețele și unele aspecte mai profunde de configurare cu alții.

Înregistrarea cu Twitter

Creați o nouă aplicație Twitter pe tabloul de bord al aplicației Twitter:

Clic Creați aplicația nouă-Am constatat că URL-ul de apel invers a fost inutil, dar deocamdată am folosit substituentul http://mydomain.com/user/security/auth.

Iată noua pagină a aplicației noastre:

Iată-l Setări pagină:

Iată-l Cheile și accesoriile pagină. Aici, trebuie să copiem Cheia pentru clienți (cheia API) și Secretul consumatorilor (Secretul API):

Aceste chei intră în fișierul nostru mp.ini, care este citit în $ config pentru a configura AuthClient pentru Twitter.

Înregistrați aplicația noastră Facebook

Apoi, hai să vizităm consola dezvoltatorului Facebook și Adăugați o aplicație nouă:

Vom alege să creați o Site web WWW aplicație pentru moment:

Furnizați numele aplicației noastre:

Și să ne colectăm noi ID-ul aplicației:

Ei solicită toate informațiile regulate, cum ar fi adresele URL:

Și apoi ne puteți găsi pe noi Planificatorul întâlnirilor app în listă:

Iată tabloul de bord Facebook pentru aplicația dvs.:

Înregistrați-vă cu Google

API-urile Google sunt un pic mai complexe decât Twitter și Facebook, deci UX este puțin mai greu de urmat. Dar, practic, odată ce creați o aplicație, aveți nevoie de cheile OAuth 2.0, pe care le obțineți prin deschiderea zonei de aplicații pe ecranul de acreditare:

Asta te duce aici:

Din motive de securitate, Google (și LinkedIn) necesită o listă completă a exactelor căi și parametrii de adrese URL care ar putea fi utilizate în timpul unei secvențe OAuth. În timpul dezvoltării, acest lucru poate necesita o mulțime de ajustări - chiar și pentru testarea de la localhost.

După ce le-ați introdus, le veți vedea mai jos:

Google face o treabă plăcută de a vă ajuta să configurați ecranul de consimțământ pe care utilizatorii dvs. îl vor vedea atunci când încearcă să-și înregistreze sau să le conecteze Contul Google la Planificatorul întâlnirilor:

Înregistrează-te cu LinkedIn

LinkedIn este destul de simplă în comparație cu Google. Aveți nevoie de detaliile de bază pentru aplicația dvs.:

La fel ca Google, ele necesită toate adresele URL pe care le veți utiliza în dezvoltarea și producția. De asemenea, puteți obține cheile de pe această pagină:

Introducerea cheilor în fișierul nostru de configurare

În Protejarea cheilor de la GitHub, am descris în detaliu modul în care folosesc un fișier de configurare pentru a stoca toate cheile mele în afară de magazia mea GitHub. Apoi, includ acest fișier la începutul fișierelor de configurare Yii. Acest lucru mă împiedică să verific în mod accidental cheile mele în depozitul meu și să-mi compromită conturile. 

Am plasat atât cheile de Twitter și Facebook, cât și secretele /var/secure/mp.ini în afara depozitului:

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 "

Aici este din nou codul din \ Frontend al \ config \ main.php care include aceste setări și stabilește variabilele individuale de configurare:

 Aplicația "frontend", "basePath" => dirname (__ DIR__), 'bootstrap' => ['log'], 'controllerNamespace' => 'class' => 'yii \ authclient \ clients \ GoogleOpenId'], 'facebook' => ['class' => 'config [' oauth_fb_secret ']],' twitter '=> [' class '=' > 'Yii \ authclient \ \ clienții Twitter', 'consumerKey' => $ config [ 'oauth_twitter_key'], 'consumerSecret' => $ config [ 'oauth_twitter_secret'],],],], 'urlManager' => [

Actualizarea schemei pentru memorarea cheilor de sesiune

Acum, că suntem gata să scriem cod pentru a integra înregistrarea socială și datele de conectare, avem nevoie de baza de date pentru a crea un Auth tabelul care va stoca serviciul social, codul său de identitate pentru persoană și numele de utilizator pentru persoana respectivă în Planificatorul de întâlniri:

./ yii migrați / creați instrumentul create_auth_table Yii Migration Tool (bazat pe Yii v2.0.2) Creați noua migrare '/Users/Jeff/Sites/mp/console/migrations/m150227_235635_create_auth_table.php'? (da | nu) [no]: da Migrația nouă a fost creată cu succes.

Iată cum arată migrația:

db-> driverName === 'mysql') $ tableOptions = 'SETAREA CHARACTERULUI utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> createTable ('% auth', ['id' => Schema :: TYPE_PK, 'user_id' => Schema :: TYPE_BIGINT. TYPE_STRING "NU NULL", "source_id" => Schema :: TYPE_STRING. 'NOT NULL',], $ tableOptions); $ this-> addForeignKey ('fk-auth-user_id-user-id', '% auth', 'user_id', '% user,' id ',' CASCADE ' „);  funcția publică jos () $ this-> dropForeignKey ('fk-auth-user_id-user-id', '% auth'); $ This-> dropTable ( '% auth');  

Iată rezultatul când îl executăm:

./ yii migrați / up Instrument de migrare Yii (bazat pe Yii v2.0.2) Total 1 migrare nouă ce urmează a fi aplicată: m150227_235635_create_auth_table Aplicați migrarea de mai sus? (da: nu): da *** aplicând m150227_235635_create_auth_table> creați tabelul % auth ... terminat (timpul: 0.016s)> adăugați cheia străină fk-auth-user_id-user-id:  (user_id) referințe user user (id) ... făcut (timpul: 0.012s) *** aplicat m150227_235635_create_auth_table (time: 0.033s). 

Încă o dată, am folosit generatorul de cod Yii Gii pentru a crea modelul Auth:

În cele din urmă, tabelul Auth va conține conținutul astfel:

Adăugați AuthChoice Widget la Planificatorul întâlnirilor

Aplicația AuthChoice a lui Yii2 face o treabă excelentă de a implementa butoanele de conectare pentru fiecare serviciu pe care îl configurați. Și procedează astfel în ordinea în care ați configurat seria de servicii și chei (pentru ao schimba).

Este destul de simplu să adăugați widget-ul la formularele noastre la login.php și signup.php:

Sau conectați-vă la unul dintre următoarele servicii:

['site / auth', 'mode' => 'login'], 'popupMode' => false,])?

Iată pagina noastră de înscriere acum:

Pentru utilizatorii existenți care sunt conectați, am creat o modalitate ușoară de a le conecta contul. Se numeste Conectați conturile sociale pe pagina cu setări de profil:

Dacă faceți clic pe LinkedIn, aici este ecranul lor OAuth care vă va cere să acordați permisiunea Planificatorului întâlnirilor: 

Iată ecranul pentru Google:

Dar ce se întâmplă când utilizatorul ne permite să împărtășim detaliile contului nostru social? Să trecem prin codul pe care l-am scris pentru a procesa acțiunile utilizatorilor.

Procesarea permisiunii OAuth

\ \ front-end controlere \ SiteController.php procesează intrarea AUTH acțiune la această funcție onAuthSuccess:

 / ** * @inheritdoc * / acțiunile funcției publice () return ['error' => ['class' => 'yii \ web \ ErrorAction', 'captcha' => \ captcha \ CaptchaAction ',' fixedVerifyCode '=> YII_ENV_TEST? 'testme': null,], 'auth' => ['class' => 'yii \ authclient \ AuthAction'; 'successCallback' => [$ this,'onAuthSuccess '];  

Cei mai buni clienți OAuth furnizează informații similare într-o matrice de proprietăți similare, cu excepția Twitter. Twitter a întârziat la jocul de partajare a adreselor de e-mail, iar pentru MVP-ul meu nu va merita munca suplimentară pentru a-l configura acum. Google și Facebook sunt mult mai răspândite.

În primul rând, colectez detaliile serviciului și colectez cât mai multe date personale: e-mail, nume și prenume, nume complet și, în special, ID-ul extern al acelui utilizator la acea rețea socială:

funcția publică onAuthSuccess ($ client) $ mode = Yii :: $ app-> getRequest () -> getQueryParam ('mode'); $ atribute = $ client-> getUserAttributes (); $ serviceId = $ atribute ['id']; $ serviceProvider = $ client-> getId (); $ serviceTitle = $ client-> getTitle (); $ firstname = "; $ lastname ="; $ fullname = "; comutare ($ serviceProvider) caz 'facebook': $ username = $ email = $ atribute ['email']; = $ attributename ['e-mailuri'] [0] ['valoare']; if (isset ($ attributes ['displayName' $ attributes ['nume'] ['familyName']) și isset ($ attributes ['name'] ['datăName '])) $ namename = $ attributes [' name '] [ $ attributename ['name'] ['givenName']; break 'case' linkedin ': $ username = $ email = $ atribute [' email-address ']; $ firstname = $ atributele ['last-name']; $ fullname = $ firstname. ". $ lastname; pauză; cazul "twitter": $ username = $ attributes ['nume_scris]'; $ fullname = $ atribute ['nume']; // a face - remediați asistenții sociali $ email = $serviceId.'@twitter.com '; pauză;  // a face - împărțiți numele în prima și ultima cu parser $ auth = Auth :: find () -> unde (['source' => (șir) $ serviceProvider, 'source_id' ]) -> unul (); 

În ultimele rânduri de cod de mai sus, căutăm în Auth tabel pentru ID-ul extern al persoanei. Dacă acestea nu există, sunt noi pentru Planificatorul întâlnirilor. Dacă există, atunci le recunoaștem.

În mod similar, trebuie să verificăm dacă adresa de e-mail există deja, deoarece este posibil ca persoana cu adresa e-mail înregistrată anterior la Planificatorul de întâlniri.

Atunci când nu există niciun utilizator autentificat curent la MeetingPlanner.io, codul de mai jos examinează datele de intrare ale utilizatorilor. 

Dacă ID-ul extern este deja în tabelul Auth, le conectăm. A fost ușor (pentru ei)!

Dacă nu recunoaștem ID-ul, dar am înregistrat deja adresa de e-mail, îi cerem să se conecteze prin numele de utilizator și parola și apoi să le conecteze.

dacă yii :: $ app-> user-> isGuest) if ($ auth) // dacă user_id asociat cu acest login oauth este înregistrat, încercați să-l logați în $ user_id = $ auth-> user_id; $ person = noi \ comune \ modele \ Utilizator; $ identitate = $ persoană-> identificare ($ user_id); Yii :: $ app-> user-> autentificare ($ identitate);  altfel // este un nou id oauth // verifica mai întâi dacă știm adresa de e-mail dacă (isset ($ email) && User :: find () -> unde (['email' => $ email] există ()) // e-mailul este deja înregistrat, cereți persoanei să-și conecteze conturile după conectarea în Yii :: $ app-> getSession () -> setFlash ('error', [Yii :: t (' E-mailul din acest cont client este deja înregistrat. Mai întâi, conectați-vă folosind numele de utilizator și parola, apoi conectați-vă la acest cont în setările profilului dvs. ", ['client' => $ serviceTitle]); $ This-> redirecționa ([ 'conectare']);  altceva if ($ mode == 'login') // încercau să se conecteze cu un cont neconectat - cere-i să se autentifice în mod normal și link-ul după Yii :: $ app-> getSession () -> setFlash ', [Yii :: t (' frontend ', "Nu recunoaștem utilizatorul cu acest e-mail de la client".) Dacă doriți să vă înscrieți, încercați din nou mai jos. Cont planificator, conectați-vă mai întâi la numele dvs. de utilizator și la parola dvs. Apoi vizitați setările profilului dvs. ", ['client' => $ serviceTitle]),]); $ This-> redirecționeze ([ 'înscriere']); 

În continuare, dacă au pornit pe pagina de conectare când au dat clic pe butonul cont social și nu recunoaștem ID-ul extern sau adresa de e-mail, le redirecționăm la pagina de înscriere și le cerem să încerce din nou - de la pagina de înregistrare.

Dacă sunt conectate de la pagina de înscriere, ne asigurăm că noul utilizator nu riscă să aibă un nume de utilizator dublu (al unui utilizator pre-existent al Planificatorului de întâlniri). În acest scenariu, noi extindem numele de utilizator cu un șir aleatoriu pentru moment. Și le înregistrăm ca utilizator nou la Planificatorul întâlnirilor cu o parolă (pe care nu o vor avea cu adevărat).

altfel daca ($ mode == 'signup') // inscrie un cont nou folosind oauth // cauta numele de utilizator care exista deja si diferentiaza-l daca (isset ($ username) && User :: find () -> unde ['username' => $ username]) -> există ()) $ username. = Yii :: $ app-> security-> generateRandomString (6);  $ parola = Yii :: $ app-> security-> generateRandomString (12); $ user = utilizator nou (['username' => $ username, // $ attributes ['login'], 'email' => $ email, 'password' => $ password, 'status' => User :: STATUS_ACTIVE ,]); $ User-> generateAuthKey (); $ User-> generatePasswordResetToken (); $ tranzacție = $ user-> getDb () -> beginTransaction (); dacă $ ($ user-> save ()) $ auth = noul Auth (['user_id' => $ user-> id, 'source' => $ serviceProvider, // $ client-> getId => $ serviceId, // (șir) $ atribute ['id'],]); dacă ($ auth-> save ()) $ transaction-> commit (); Yii :: $ app-> user-> autentificare ($ utilizator);  altceva print_r ($ auth-> getErrors ());  altceva print_r ($ user-> getErrors ());  // înregistrarea finală

În ultimii pași de mai sus, adăugăm detaliile contului social extern la adresa Authtabel pentru recunoașterea viitoare.

Conectarea conturilor planificatorului de întâlniri existente

Dacă provin din fila Conturile sociale de pe pagina de profil a utilizatorului (în locul paginii noastre de conectare sau de înregistrare), atunci trebuie doar să adăugăm detaliile contului lor extern Auth, și mutați numele lor de conectare Utilizator :: STATUS_ACTIVE. (Amintiți-vă că utilizatorii care sosesc din legăturile de invitație ale Planificatorului de întâlniri, dar care nu s-au înregistrat niciodată, Utilizator :: STATUS_PASSIVE Mod.)

 altceva // utilizatorul deja conectat, conectați conturile dacă (! $ auth) // adăugați autorul autorului $ auth = nou Auth (['user_id' => Yii :: $ app-> user-> id, sursă '=> $ serviceProvider,' source_id '=> $ serviceId,]); $ Auth-> validate (); $ Auth-> Salvare (); $ u = Utilizator :: findOne (Yii :: $ app-> user-> id); $ u-> status = Utilizator :: STATUS_ACTIVE; $ U-> actualizare (); Yii :: $ app-> session-> setFlash ('succes', Yii :: t ('frontend', contul dvs. de serviceProvider a fost conectat la contul dvs. Planificator de întâlniri. În viitor vă puteți conecta cu un singur clic pe logo-ul său ", array ('serviceProvider' => $ serviceTitle)); 

Iată cum arată acest lucru (în viitor, voi completa informațiile de numire din informațiile OAuth - nu sa terminat încă):

În încheiere

Trebuie să recunosc că impactul conexiunilor de lucru OAuth cu servicii importante precum Google, Facebook și LinkedIn este destul de dramatic. Înregistrează și utilizează în mod regulat Planificatorul de întâlniri atât de ușor și accelerează autentificarea viitoare. Este într-adevăr un fel de incredibil.

Întâlnirea Planificator sa reunit cu adevărat în ultimele luni. Încearcă autentificarea socială și înregistrarea chiar acum! Urmăriți tutorialele viitoare în Building Your Startup With PHP series - există o mulțime de caracteristici amuzante care apar în timp ce produsul se îndreaptă spre MVP.

De asemenea, încep să experimentez WeFunder pe baza punerii în aplicare a noilor reguli de finanțare ale SEC. Vă rugăm să luați în considerare profilul nostru. Pot să scriu despre asta mai mult ca parte a seriei noastre.

Vă rugăm să nu adăugați întrebările și comentariile de mai jos; În general, particip la discuții. Puteți să mă contactați și pe Twitter @reifman. Salut cererile de teme și teme.

Dacă doriți să știți când vine următorul tutorial Yii2, urmați-mă @reifman pe Twitter sau verificați pagina de instructor. Pagina mea de instructor va include toate articolele din această serie de îndată ce vor fi publicate. 

Link-uri conexe

  • Planificator de întâlniri: Programați prima întâlnire
  • Profilul de finanțare a planificării întâlnirilor
  • Programarea cu Yii2: Noțiuni de bază
  • Ghid pentru Extensia AuthClient pentru Yii 2
  • Yii2 Documentație bibliotecă OAuth2
  • Schimbul de dezvoltatori Yii2
Cod