Slide 1

Slide 1 text

Adding Facebook Auth as an Afterthought Dallas PHP | August 2017

Slide 2

Slide 2 text

Use Case Locally housed user management system. Willing to trust outside party as an authority on user identity. Desires easy/social login for smoother experience.

Slide 3

Slide 3 text

Process Overview Your Site! Facebook! "I HAS GUY"

Slide 4

Slide 4 text

Process Overview Your Site! Facebook! "YOU HAS AN BOB"

Slide 5

Slide 5 text

Process Overview Your Site! Facebook! "HAV BOB, PRIVATE DETAILS, EMAIL, ETC PLOX"

Slide 6

Slide 6 text

Process Overview Your Site! Facebook! "SURE THING MY DUDE"

Slide 7

Slide 7 text

Process Overview Your Site! Facebook! "I SO HAVE THAT BOB" "WHOA ADDING NEW BOB" "WELCOME, BOB"

Slide 8

Slide 8 text

Process Overview User initiate a request to log into your site. Site sends user to Facebook Authentication, with instructions on how to return after they accept. Facebook sends them back to your app. App uses authorisation to request solid identification. App makes judgement on what to do with identification. (Login, or Create+Login)

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

$composer require facebook/graph-sdk

Slide 12

Slide 12 text

developers.facebook.com

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

$FBConfig = [ 'app_id' => 'YOUR_APP_ID', 'app_secret' => 'YOUR_APP_SEKRET', 'default_graph_version' => 'v2.10' ];

Slide 16

Slide 16 text

$FB = new Facebook\Facebook($FBConfig);

Slide 17

Slide 17 text

$FB = new Facebook\Facebook($FBConfig); $Helper = $FB->GetRedirectLoginHelper();

Slide 18

Slide 18 text

/auth/fb-init $CallbackURL = GetURL('/auth/fb-confirm'); $Permissions = [ 'email' ]; $FacebookURL = $Helper->GetLoginURL( $CallbackURL, $Permissions ); Goto($FacebookURL);

Slide 19

Slide 19 text

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

/auth/fb-confirm <1> // check if we got an oauth token from facebook's flow try { $Token = $Helper->GetAccessToken(); } catch(Throwable $Err) { /* refused, error, etc */ return; } if(!$Token) { return; }

Slide 22

Slide 22 text

/auth/fb-confirm <1> Exceptions Primary Causes: ● Invalid tokens, expired tokens. ● Some sort of foolery where the token was changed enroute. ● User took too long to say OK. ● The user just said no. You NEED to know: ● It just didn't work. Bail out on attempting ID.

Slide 23

Slide 23 text

/auth/fb-confirm <2> // try to trade the token for a longer lasting one try { $Token = $FB->GetOAuth2Client() ->GetLongLivedAccessToken($Token->GetValue()); $FB->SetDefaultAccessToken($Token->GetValue()); } catch(Throwable $Error) { return; }

Slide 24

Slide 24 text

/auth/fb-confirm <2> Exceptions Primary Causes: ● Invalid tokens, expired tokens. ● For some reason Facebook has revoked the token. You NEED to know: ● It just didn't work. Bail out on attempting ID.

Slide 25

Slide 25 text

/auth/fb-confirm <3> // use the authorisation to get user data we need to id user. try { $About = $FB->Get('/me?fields=id,name,email')->GetGraphUser(); } catch(Throwable $Error) { return; } $Info = [ 'FBID' => $About->GetID(), 'Name' => $About->GetName(), 'Email' => $About->GetEmail(), 'Token' => $Token->GetValue() ]; if(!$Info['Email']) { return; /*?*/ }

Slide 26

Slide 26 text

/auth/fb-confirm <3> Exceptions Primary Causes: ● Invalid tokens, expired tokens. (How slow is your server lol) ● For some reason Facebook has revoked the token. You NEED to know: ● It just didn't work. Bail out on attempting ID. ● It worked but I cannot ID them: (no email address) ○ Bail out ○ "{$Info['FBID']}@facebook.com"

Slide 27

Slide 27 text

Finally

Slide 28

Slide 28 text

/auth/fb-confirm <4> // find id or generate id for user. $User = User::GetByEmail($Info['Email']); if(!$User) { try { $User = User::Create($Info); } catch(Throwable $Err) { return; } } $User->BeginSession(); Redirect('/');

Slide 29

Slide 29 text

Token Reuse

Slide 30

Slide 30 text

try { $FB = new Facebook\Facebook($FBConfig); $FB->SetDefaultAccessToken($Who->Token); $TokenInfo = $FB ->Get("/debug_token?input_token={$Who->Token}") ->GetGraphObject(); } catch(Throwable $Error) { return FALSE; } return (Bool)$TokenInfo->GetField('is_vaild'); Bool IsTokenValid(User $Who)

Slide 31

Slide 31 text

Graph SDK Basics

Slide 32

Slide 32 text

Facebook API Main Methods $FB->Get(String "/endpoint-uri") $FB->Post(String "/endpoint-uri", Array $Data)

Slide 33

Slide 33 text

Facebook API: Get() try { $About = $FB->Get("/me?fields=id,first_name,last_name") ->GetGraphObject(); } catch(Throwable $Err) { return; } echo $About->GetField('first_name');

Slide 34

Slide 34 text

Facebook API: Post() try { $Post = $FB->Post( // requires publish_actions "/me/feed", [ "link" => $WebsiteURL, "message" => $Message ] ) ->GetGraphObject(); } catch(Throwable $Err) { return; } echo "Posted Post #{$Post->GetField('id')}";

Slide 35

Slide 35 text

Some Things you can do... Get information Post status updates Upload photos Respond to event invites Check friendship status Schedule page posts Tag places Get payment status

Slide 36

Slide 36 text

All Calls Must Be Caught Any time you make a call that depends on valid auth token make sure the library was able to do its job. try { ... } catch(Throwable $Error) { /* bail out */ } Any time you consume data, make sure it makes sense, and contains all the data you need. if(...data seems invalid...) { /* bail out */ }

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

Dallas PHP August 2017 Bob Majdak Jr @bobmagicii Graph SDK Documentation developers.facebook.com /docs/reference/php Graph SDK github.com /facebook/php-graph-sdk Graph API developers.facebook.com /docs/graph-api Demo Project github.com /bobs-archive-of-stuff /dallasphp-201708-fbauth