GUS CLASS: Hello Google+ developers, and welcome to
this week's episode of Google+ Developers Live.
I'm Gus Class, a developer programs engineer on the
Google+ team.
And today I'm going to be showing you some best
practices for sign in.
If you were watching our episode from last week, I had
started out by just at the top of the charts, what you're
trying to do with sign in is get the user to sign in.
And there's a couple of things you can do to kind of
encourage the user to sign in more and to increase the
likeliness that they're going to sign in onto your site.
And when you sign in the user onto your site, you get all
sorts of benefits like that user is then able to
contribute to your site in an easier way.
And you're able to get to that user's data, which allows you
to draw the user into your site more.
So if you look at my screen, you can see the site as it was
rendered last week.
And so this is just a copy of the demo from last week.
And in this copy, you can see the Sign In button prominently
displayed on the right of the screen.
You can see that encouragement to get the user to
sign in on the left.
And when the user signs in, they get this nice experience
where their profile is reflected back to them.
And then it bounces to kind of draw to their attention that
they're signed in.
So here's the basic experience.
And here's the better experience.
So let's disconnect.
So what I want to show you today is
kind of the next step.
What happens before the user signs in?
And if you look at this site, I've made one change to this
site, and this change is kind of a future-facing feature for
"Is too cute!" And what this forward-facing feature is, is
it allows the user to do something with their photos.
I haven't determined what it is yet, but at some point I'm
going to add a feature that brings in a user's photos from
their Google+ activity stream.
So what I've done is I've created some code here that
just does the basics, and it signs them in with Google+.
Now after the user signs in, this icon
appears in the top right.
And that icon is indicating to the user that you click here,
and your photos will be accessed.
So if you look at the photos here, you can see here's all
the photos that already exist inside of my activity stream
on Google+.
And let's just take a quick look at the code
for how this is done.
We've actually shown very similar code in other GDLs.
So I don't want to spend too much time on this.
But this is code that we see a lot out there, because people
are doing interesting things with a user's Google+
activities.
So at a high level, what we do is we
construct that gapi client.
And then we perform a request against plus activities list.
And we set the user ID to the currently authorized user, get
their public collection, and then we traverse that list of
elements that are returned looking for images.
And so I just have a string inside of my helper module,
and that contains the URLs that at some point in the
future, I'll do something with.
So what if, though, I want to get as many photos as possible
from my users?
And so I want to use additional data points.
So what I've done is I've made another
version that is better.
And what this better version does is it also tries to
retrieve files from a user's Google Drive.
And in doing this, you're able to bring in more
content for your site.
And you're able to allow the user to get to more of their
data without having to go through more effort.
So I'll sign in again, and you can see that I haven't
refreshed the page yet.
But I'll sign in again, and now you can see an additional
scope being requested.
The little element here that says "View the files and
documents in your Google Drive" has been added because
I've requested an additional scope.
And now I just accept.
And now after the user signs in, and the user clicks on
this little icon here with the photos, you can see there's
more stuff here, most notably the assets that I
created for this site.
So all these files on the top here are files
from my Google Drive.
So this is great.
So now you have these two scopes.
So you can do all sorts of additional things
you couldn't do before.
Before going on, let's take a look at how we added that
Drive scope.
So here is the code markup for rendering that Sign In button.
And on the top, you just see that data scope attribute, and
it's set to just Google APIs auth plus login.
Now this is the Google+ scope.
And this is what is actually implicit inside
of the Sign In button.
But I'm explicitly showing it so that it's
easier for you to read.
And in the second case, what we've done is we've added an
additional scope.
So when you want to use additional Google APIs you
need to set up your console project to have
those services enabled.
And then you need to request both the scopes.
So these scopes inside of that data scope field are just
space delimited.
And by doing this, we're then requesting
both of those scopes.
And so I'm also doing that photos list that I'm doing
from Google+ with the equivalent from Google Drive.
And don't worry too much about this code.
I just want to show that it's very similar code when you're
accessing content from multiple data sources using
the Google APIs.
So this just does a similar query where it says Drive
files list.
And then I'm looking for files by MIME type.
And this will just return all the images that I have on my
Google Drive.
So we have both of these scopes.
And when the user sees it, they then say, oh, I'm going
to be granting this application access to both my
Google+ account and my Drive account.
For some users--
let's just say hypothetically--
this could be something that would turn them away.
And you don't want that to happen, because you want users
to sign in.
So you can do something awesome.
You can do something amazing.
And you can actually do what I like to call, dynamically
generating these scopes.
So let's turn it back to awesome and reload the page.
And so now if you look at the page, you can see this sort of
signal I'm giving the user when they highlight over the
Sign In button.
The behavior is a little bit different.
The button grays out when the user highlights over it.
And now when the user clicks the button, something
different happens.
I prompt the user, choose what you share with us.
And I give them two options.
I say, I really want to see your Google Drive files,
because we want to allow you to do
something with these photos.
But if you just want to use Google+, and you don't trust
us with your Drive files, or you have sensitive stuff on
there, you can just choose the other.
So when you click this, the Sign In button then appears
inside the dialogue.
And when the user signs in, the scopes that they've
selected appear here.
So because I selected Google Drive, now I see "View files
and documents in your Google Drive" as well
as the Google+ scope.
Now I'll cancel here.
We'll go back here.
And we'll render this again.
And if I were to switch which instead to say only Google+
and I sign in, I get just only Google+.
So let's make sure that this is really doing what I think
it's doing, and let's look at those photos again.
So because of the requested scopes, I'm just now seeing my
Google+ photos.
And now if I were to disconnect and reconnect, you
will see that all my photos from Google+ and Google Drive
now will appear inside of that photos area.
Now there's a couple of things that I'm doing here, and
there's a couple of things that are really worth
mentioning.
When you do this, you're losing a lot of the built-in
functionality of the Sign In button.
And you're losing it because you're managing this other
dialogue in addition to that Sign In button.
So when you do this, if you choose to carefully select
these scopes and allow the user to dynamically generate
these scopes, make sure that you test the heck out of it.
Because there's a lot of simple ways that you can kind
of do this and make the experience not as good.
So let's see how I'm doing it if I load up the code here.
The first thing that I have to do when dynamically rendering
these scopes is to enable explicit render.
So what explicit render means is when the JavaScript for the
+1 button renders, which also contains the JavaScript for
rendering the Sign In button, instead of just rendering the
buttons immediately after the HTML is loaded, what you'll be
doing is you'll be programmatically rendering
that Sign In button.
And so when you programmatically render the
Sign In button, you then can manage that scope attribute
dynamically.
So I also want to emphasize that incremental auth is
something that's kind of more specific to--
you would encounter it in Android.
And this is not that.
This is just managing the scopes that are rendered
inside of that Sign In button so that the user can
selectively turn on or off some of those scopes.
So here's how you do explicit render, the first part.
You have to set the Google API scripts in JavaScript to
explicitly render that Sign In button.
And so because I'm loading the JavaScript asynchronously, at
the top of that JavaScript client library boilerplate
code, I'm setting this global variable gcfg to have the
attribute parsetags set to explicit.
And then inside of my actual application JavaScript, I can
programmatically render the button through this API call.
And in my particular case, I'm storing the client ID and the
auth scopes inside of that helper module.
So this sort of simplifies for me.
But you can pass strings here.
You can do it a number of different ways.
And that first attribute that is passed to that gapi sign in
render is going to be the target container that's going
to render inside of your HTML.
So I've just got a span inside that dialogue, and then I
target the span.
And as soon as I call render, the Sign In button appears
inside of there.
And I'm also doing something--
so when I render those scopes insider of that dialog again,
I'm just going to append the Drive scope to just a base
scope that I'm using.
And when the user says Google Drive and Google+, then that
Drive scope is appended to the scope string, and then when
the button is rendered, you see both the scopes.
And there's something else that I'm doing.
Because of the way that I'm managing the dialogue, I end
up also having to do this sort of last bit of flair where I
have to re-show that little interactive Sign In button by
looking for when the user cancels the sign in dialogue.
Because I do something where I'm hiding the button around a
lot and then re-showing it.
So I'm not going to recommend right off the bat that you can
do this, but you can do this.
And I'm showing you just so that you can sort of see all
of the various ways you can really flair up your site with
personalization and a kind of a look and feel that is unique
to what you like.
So here's the Sign In button.
Now because I haven't yet rendered the Sign In button,
what I'm doing is I'm showing this dialog with the Sign In
button in the background.
Now when I click Google Drive or Google+, or only Google,
the Sign In button hides inside of the background, and
then it renders again inside of that dialogue.
And this is just something that I like.
I just wanted to have this sort of experience.
And I hooked in to the various pieces of Google+.
So that here again you can see that in the background I'm
hiding the Sign In button now.
And I'm listening for this cancel event.
So when I click Cancel, there's an error that's
returned to that on sign in callback.
And then listening for that error, I can then show the
Sign In button again.
I'll try to talk a little bit more about this topic of
things you can do when you're handling errors inside the
Sign In callback.
But it's going to saved for a future episode of the sign in
best practices.
So this is really all I had to show for you today in terms of
experience.
But I have a great example of someone doing this dynamic
scoping from the real world, Jolicloud.
And if you look at their site, you see that sign in
experience that I simulated before.
So here's a Sign In button.
Here's a Sign In with Google button that's prominently
displayed on the front of their site.
And when I click this, here is one of these dialogs.
And you can select or deselect the features that you want to
turn on and off.
And when you do this, you feel like you can trust Jolicloud
with the things you are sharing.
So I really like when sites do this.
Because it allows me to control upfront the
information that I'm sharing.
And it doesn't surprise me.
I don't ask myself, why is this site asking for access to
my Google Drive?
I'm suspicious of that.
So by doing this you can create a much more trusting
connection with the user.
And you can increase the likeliness that users will
actually sign in to your site.
And once the users are signed into your site, then you have
a lot of tools at your disposal for driving up
engagement.
So that's pretty much it for today's episode.
I have a couple of announcements.
The first is that the code from the last episode is now
inside of our GitHub pages.
So if you're interested in taking a closer look or
running through the demo yourself, the code's there.
And also this week, we launched PhotoHunt in C#.
Sharp.
And so now if you are a Windows developer and are
interested in taking a deeper look at Google+ sign in
integrations, that sample is available for you.
And that's it.
So please watch our Google+ Developer Live shows every
Tuesday at 2:30.
So thanks for tuning in and look to see you next time.