CHRIS CARTLAND: Welcome to Google+ Developers Live.
My name is Chris Cartland.
And I'm a developer programs engineer working on the
Google+ platform.
YANIV YAAKUBOVICH: And I'm Yaniv Yaakubovich.
I'm a product manager in the Google+ platform.
CHRIS CARTLAND: Thanks for joining us this week.
Today we're going to talk about verifying tokens that
you receive from your client apps on your server.
So first we're going to talk about when you need to do
this, when it's important.
We're going to talk about why and the kind of things you
want to avoid in your app.
And we're also going to tell you how to do it.
And we're going to look at some code that we have on
GitHub to actually show you how to get this done.
YANIV YAAKUBOVICH: And while we're doing this broadcast,
you can comment and questions for us either on our Google+
or channel on YouTube, wherever you're
watching this video.
CHRIS CARTLAND: Yeah, and we'll be sure to get those
questions at the end.
So first of all, we have to talk about
what we're doing here.
We're talking about requests coming from your client to
your server.
So if we look on my screen here, we can see that we're
going to make requests.
And there's two things that you can do.
One is that you could send an authorization code.
And we cover that in all of our Quick Starts.
So you can check those out at developers.google.com/plus.
Look for the Quick Starts.
Pick your favorite language.
And that's one way to establish an authenticated
connection with your client and your server.
Today we're going to talk about a different way to do
this, and that is by sending either an ID token or an
access token to your server.
The code for this is available on GitHub.com/googleplus for
either the Quick Starts or for the samples that tell you how
to verify the tokens.
So first a little background.
What are these two different types of tokens that we're
going to be talking about today?
The first is an ID token.
And an ID token contains information about the user and
who they are.
And it's also cryptographically signed by
Google so that you can verify that this is a real token.
YANIV YAAKUBOVICH: And we'll show you later in the code how
we can verify that it's a Google token
and not other token.
CHRIS CARTLAND: Exactly.
An access token is a bearer token that can be used to make
API calls to Google.
And you need to make sure that you verify those every time
your server receives them as well.
If you are going to decide which one of these to use,
remember that an ID token is a way to identify who a user is
very quickly.
And an access token is required if you need to then
make further requests to Google's APIs.
So depending on what you want to do, if you want to be fast
and just identify the user, use an ID token.
If you want to make API calls to Google, you should use an
access token.
And all of this, I'll say this again, you should use the one
time code flow instead of doing this first.
It's preferred because it's more secure, because that code
can't be intercepted.
And it also gives you a little more power, which you can read
about in our documentation.
So you should try to use the code flow.
You also want to make sure that, if possible, you should
authenticate a session so you can make multiple requests.
YANIV YAAKUBOVICH: In cases that you don't have a session,
then the solution that we are presenting
today will be relevant.
CHRIS CARTLAND: Exactly.
So if you are not able to establish multiple requests in
one session, then you need to authenticate all requests.
And to do that you can send, say, the ID token or the
access token to do that.
If you don't have the authorization code, then you
have no choice but to use something like sending the
access token to your server in order to make the request.
And right now, iOS doesn't have that.
So you'll need to do that.
YANIV YAAKUBOVICH: And we're looking into solving it in the
near future.
CHRIS CARTLAND: So we want to show you briefly how to get
these tokens before we talk about how to verify them.
So on Android, if you want to get an ID token you can use
Google AuthUtil.
Use this syntax that I have on the screen.
And make sure that you do this in an AsyncTask so that it
doesn't block anything in the app.
And you'll get a string back that you can then send
securely to your server.
If you want to get an access token, you do a
very similar thing.
But you change the third argument to match the syntax
that I have on the screen here.
And these are just the way that your client will get the
token to send to your server.
On the web, you do it a little bit differently.
You start with the call back from the sign in.
And in your auth result, you can get both the ID token and
the access token as strings.
And you can send those to your server as well.
Web is most likely the one where you're going to
use the code flow.
So if you can help it, you probably
won't have to do this.
On iOS, you get an access token in the auth object from
finished with auth.
And you can send that string to your server.
This is the place you're most likely to use these methods
because we don't have an authorization code available.
So why do we want to verify this tokens?
Why is that important?
YANIV YAAKUBOVICH: Well, there are two main cases.
One is when you have an invalid token.
Either the token expired or the token is from an app that
is not really your app, or when you have a bad client.
You want to give an example for that?
CHRIS CARTLAND: Yeah, so a bad client would be like if you
have an attacker who gets users the sign in to their app
and gets some to hit the consent screen.
That person, that developer, could send tokens and make
requests to your server.
And they would be real tokens.
They would actually be issued by Google.
So just check to make sure that they are real.
And then check to see what user was attached to that.
You may give an attacker access to a user's information
even though that user never signed into your app.
YANIV YAAKUBOVICH: And that's the reason that you're
verifying that this token will run for your app based
on your client ID.
CHRIS CARTLAND: Absolutely.
So it's very critical that you check to make sure that this
token for your app and not just
someone's app on the internet.
YANIV YAAKUBOVICH: Right.
CHRIS CARTLAND: So how we're going to do
this is do two things.
First, we check to make sure that the
tokens are made by Google.
YANIV YAAKUBOVICH: And then you want to check that these
tokens are meant for your app using the client ID.
And you can set the client ID and verify
it in the dev console.
CHRIS CARTLAND: So yeah, in the Google API console when
you set up your project you will create a web client ID.
And so depending on what type of token you're sending, you
have to make sure that the client ID for that token is
the one that you're checking on the server.
YANIV YAAKUBOVICH: And you're most likely to have a
different client ID for each of your apps.
So for your Android app, you'll have one client ID,
another one for your desktop app, and another for your iOS.
CHRIS CARTLAND: That's correct.
So depending on which token you have, you have to do
slightly different steps.
Let's start with the ID token.
First, we're going to check to make sure
it's issued by Google.
So how do we do that?
YANIV YAAKUBOVICH: Well, you check the signature using the
Google API.
And we'll show you the code that does it.
And then you do the same for access token.
You call the token in for API.
The second step would be to check your client ID.
You compare the client ID with the token that you just read
on the ID token.
And again, you do it with the token API response and the
token info response to verify the access token.
CHRIS CARTLAND: Exactly.
YANIV YAAKUBOVICH: Step number one, number two are essential
to verify the tokens.
And step three is only the stuff that we're using for
this example.
You can use any other step that is relevant for your app
at this stage.
And we'll show you just one of those examples.
CHRIS CARTLAND: Exactly.
So we're going to show you the first two steps to make sure
that it's verified.
And then we're going to also get the user ID, because
that's a useful thing for your client to know.
Once you've authenticated with your server, now your client
will know who the user is.
YANIV YAAKUBOVICH: Now do you want to repeat, for those who
didn't hear us, when do you need to check ID token and
access token?
Do you need to do it every time that you call the API or
per session?
CHRIS CARTLAND: Yeah, yeah.
So the first time you make a request from that client, you
always need to check it in some way.
So if you've done an authorization code, that is
your first connection to authenticate between your
client and your server.
You may not have that.
So again, the first time you send an ID token or access
token, you need to do that.
Every time that you get a new ID token or access token from
your client that you can't trust, you need to make sure
that you verify it.
If you have the option, though, you should try and
authenticate a session, though, so you don't have to
do this check for every request that comes in from
your clients.
YANIV YAAKUBOVICH: So ideally you'll do this check once you
start a session.
As long as the session is alive, you'll assume that
these steps, these tokens are already valid, and you
continue without checking it again.
CHRIS CARTLAND: Yeah, and if the session is already valid
you probably don't even need to send the ID token or the
access token again, because you already know who is
on the other end.
So great, let's look at some code.
We have samples available in five languages.
We're going to look at GitHub before PHP today.
But you can pick your favorite language and see how it works.
The logic is the same in all of them.
So you'll even get the same responses in your client apps.
So first on Google+, we have this G+ verify token PHP.
It looks very similar to our Quick Starts.
So if you haven't done that yet, you should do the Quick
Start first, because we think that's the one that you're
going to need to use.
YANIV YAAKUBOVICH: They're fairly simple, very easy to
integrate, very easy to follow the examples that we have over
there with regard to allow you to spend less time on
developing for our platform and most time on developing
your actual app.
CHRIS CARTLAND: Exactly.
So the relevant piece for verifying tokens in this
sample is in verify.php.
The files are named similarly in the other
languages as well.
Great.
So this is very similar, again, to the Quick Starts.
The main difference is that we have an endpoint slash verify.
So the client, which when we run the sample is the web app,
is going to send an ID token and an access token to local
host slash verify.
And we're going to make sure that if there's an access
token, we're going to make sure that it's real.
And we're going to make sure it's for your app.
And then we're going to look at the access--
sorry, I said the wrong one.
YANIV YAAKUBOVICH: You said the access.
We'll show you how you do the access token and the ID token.
CHRIS CARTLAND: And it doesn't matter which one is which.
So we'll start by pulling the ID token and the access token
into strings in PHP.
Everything that we do in the sample is going to be returned
in this array.
So it's going to say token status is going to have
information about what tokens it received.
To start, we're going to have the ID token status.
And we're going to create an empty array to hold that
information.
So we'll check the ID token first, which we're only going
to do if the client sent an ID token.
The real easy thing about verifying the ID token in PHP
is that the client library does this for you.
So we just call client, verify ID token with the string,
which is the ID token.
And we pass the client ID as well.
YANIV YAAKUBOVICH: And the client library should be
available for you anytime that you use our apps.
If you start following the steps on the Quick Start, or
even the steps that we have in GitHub, in one of them you'll
download the client library.
And you'll have it for your server.
CHRIS CARTLAND: Yeah.
It's very straightforward.
All of the complicated stuff we've been talking about is
taken care of in this function call.
And what you get back is a JSON web token that contains
information about the user.
And we can get the Google+ user ID from the payload under
the field called sub, which stands for subscriber.
The rest of the code here just takes that information and
puts it into the ID status object, which was going to get
returned in the HTTP request.
If the token is not valid, we throw an exception.
And we know that either the token wasn't real or it wasn't
issued for your app.
One thing to keep in mind is that this client ID needs to
be the client ID that matches the token that was sent.
So if for some reason you have multiple tokens that are
registered coming from different apps
that are still yours--
YANIV YAAKUBOVICH: Like an Android app, an iOS app, and
the desktop app, all different apps that you're the publisher
of all of those.
CHRIS CARTLAND: Yeah, so if you have the tokens that have
different client ID registered, then you may need
to check this multiple times to find which client ID
matches your app.
And then we would take this information.
And we're going to return it in the token
status when we return.
That's great.
That's the ID token.
Let's take a look at the access token now.
Very similarly, we're going to create an empty array to hold
the information.
If there is an access token, then we're going to make a
request to the token info API.
So by itself, the string doesn't contain any
information.
You have to use it to ask Google for something.
And the token info API is a very easy way of finding out
who the token is issued for.
So we make this HTTP request to Google.
And we read the response back.
If the token is real, which means it is an access token
issued by Google, then you will get no
errors in your response.
If you do get an error, then you know that you have an
invalid access token.
YANIV YAAKUBOVICH: And here's the place to
handle those errors.
You can either show a message to the user or simply drop the
message from there to your log and verify what happened and
continue from there.
CHRIS CARTLAND: Yep, exactly.
Once you've verified that the token is from Google and is
real, you want to make sure that it's issued to your app.
So we check that client ID much like we
did with the ID token.
Make sure that you do this step so that you avoid the
problem where someone else's app sends their real access
token to your server.
You need to check this, otherwise you're causing
problems for you and your users.
YANIV YAAKUBOVICH: Or even the case that one app that you
developed overrides the other app, and you do some mistakes.
CHRIS CARTLAND: Yeah, so you want to make sure that you
expect the right tokens from each client.
And once you've checked those two things, you can trust the
access token is valid and meant for your app.
And in our response, we say that it was a valid token.
We can get the Google+ user ID from the token info response,
because every token that is issued in our OAuth 2.0 code
is issued for a specific user.
And so once we get that back, we know who the user is.
And they've authenticated that request.
We're going to say that the token valid, put that into a
response, and return all that
information in a JSON response.
YANIV YAAKUBOVICH: Pretty simple.
CHRIS CARTLAND: Very good.
YANIV YAAKUBOVICH: How would it look
like in other languages?
CHRIS CARTLAND: It looks almost the same
in every other language.
So we have the same structure.
YANIV YAAKUBOVICH: Same logic, just a few tweaks based on
their language, correct?
CHRIS CARTLAND: Yeah.
You have to create an actual object in Java.
You have to use different syntax, obviously, in
different languages.
But the logic and how you accomplish each of these
things is exactly the same.
And of course, you can look through the
code to figure out.
YANIV YAAKUBOVICH: And it's all in our GitHub?
CHRIS CARTLAND: Everything that we've
talked about is on GitHub.
So you should try it out for yourself.
Great.
So thank you for joining us.
Today we talked about verifying tokens.
We talked about when to do it, which is when you cannot use
the code flow, or you need to make requests, many requests,
in a way that you don't have an established session.
We talked about why you need to verify these tokens, so
that people who you're expecting to be authenticated
are making real authenticated requests.
You also need to make sure that attackers are not able to
use their tokens to get access to your users information.
And we talked about how to do that.
We have all of the information on GitHub for you to check it
out and try it yourself.
YANIV YAAKUBOVICH: Great.
We'll give you the ability to offer us questions.
Well, I don't see any questions right now on YouTube
or G+ event page.
If you have any questions, feel free to add them to our
event page.
We can take them later after this broadcast.
CHRIS CARTLAND: Yeah.
And as always, you can try out our normal documentation for
getting started with Google+ sign in at
developers.google.com/plus.
You can ask us questions in our Google+ Developers
community or on Stack Overflow with the tag Google+.
We're happy to get feedback on how well these things work for
you, how easy they are, so that we can continue to make
things better for you.
But I think that that's all we have free today.
Thank you so much for joining us today, Yaniv.
And we'd be happy to have you back.
YANIV YAAKUBOVICH: Great.
Thank you very much.
CHRIS CARTLAND: All right, thank you, everyone.
Bye.
YANIV YAAKUBOVICH: Bye.