[MUSIC PLAYING]
[WHISTLING]
MALCOLM DECK: Hi, everyone.
My name is Malcolm.
And today, Sam and I will be talking
about Firebase authentication.
SAM OLSEN: Hi, folks.
I'm Sam.
Malcolm and I work together on Firebase.
And in our time, we've seen quite a few of the patterns
and anti-patterns that people come across when building
their apps with Firebase.
MALCOLM DECK: We're going to cover a lot of ground
today and get into the nitty gritty of how Auth works.
A quick shout-out for the super advanced developers
out there who are already thoroughly
familiar with our Auth products.
At the end of this video, we'll be
delving into custom auth, which is super flexible, super
powerful, and unlocks many interesting integrations.
With that note out of the way, let's dive in.
SAM OLSEN: In my free time, I develop and maintain
my own social cat picture-sharing app.
Now, I've only worked on Firebase Auth
team for a few months or so, so I'm still getting up-to-speed.
Malcolm has helpfully offered to walk me
through some of the technical challenges and decisions
I'm dealing with.
MALCOLM DECK: Happy to help.
SAM OLSEN: When I was starting out,
I went with the most straightforward
authentication-- email and password.
It's pretty great, very simple to set up.
But I've started noticing some limitations with it.
MALCOLM DECK: What's wrong?
SAM OLSEN: Well, for one thing, I was recently
chatting with a friend who's big into app security.
She was saying that many people use the same passwords
everywhere.
She was also talking about all the different passwords
strength checks you can implement,
and that got me wondering.
MALCOLM DECK: Yeah.
Firebase will give you some basic level of password
strength requirements.
But if you want to have your own configuration,
you'll need to do that yourself.
And as far as password reuse, that is a really big concern.
Unfortunately, that's also something you'll
need to build on your own.
You could do both of these things
as client-side validation.
But ultimately, if you want to actually have real enforcement,
this also means running validation on your own service.
SAM OLSEN: Ah, OK.
That's good to know.
The other problem I've been having
is that people have been signing up with fake emails.
I know they're fake because they use bogus domains.
Someone even signed up with my work email address.
I know it wasn't me because I'm a good employee who definitely
does not use social media on his working hours.
I set up email verification to address this,
but my code is getting pretty complicated.
MALCOLM DECK: You know, Sam, there's
a way to address all of these concerns
without having you set up your own server-side code.
Email-link-based authentication solves many of these problems.
Your users would put in their email addresses.
Then they would receive an email with a link
to sign into your app.
Right away, that user has a verified email,
so you don't need to worry about bogus emails or account
squatting.
They don't have a password, so password reuse and complexity
requirements are no longer a concern.
And the code is even slightly less complicated
than doing a separate verification flow.
SAM OLSEN: Oh, this is great.
I see.
So with just these few lines of code,
I get all of those benefits.
Now, if I wanted to allow users to create a password after all,
do I have to give up this email-link sign-in?
MALCOLM DECK: Nope.
You can always just call updatePassword() on a signed-in
user with the new password.
Then you can call SignInWithEmailAndPassword()
the next time they want to sign in.
Just keep in mind that any validation
you want to do on that password needs to happen in your app.
SAM OLSEN: Cool.
I'm feeling much better about this.
By the way, I've noticed that the emails
that my users receive from Firebase
are a little on the bare side.
Is there any way I can spice them up a bit?
MALCOLM DECK: While you can update some parts of the text
content in the Firebase Console, there's
not a whole lot you can do to change the way it looks.
Email is a complex system on its own,
so Firebase only allows for a narrow range of customization.
You can, however, generate your own out-of-band code
and send the emails yourself.
We have tutorials in our documentation
that can walk you through that process.
SAM OLSEN: Ah, OK.
I got it.
My UX designer-- who is my cat, incidentally--
wanted to overhaul the emails for the site
something like this.
Sounds like I'll need to stand up my own service to send them.
MALCOLM DECK: Yep, that's definitely
something you'll need to use the Admin SDK and some other mail
service for.
SAM OLSEN: Wow, though.
This is starting to get a bit complex.
At this point, I'm standing up my own cloud service
in order to have better-looking emails
and to enforce stronger password guidelines.
When I joined Firebase, they told me it was serverless.
MALCOLM DECK: Your Auth integration
is starting to get pretty sophisticated.
You're handling UX for passwords and out-of-band email flows.
You're dealing with password strength requirements.
You're ensuring your users own the emails they've given you.
While it's great you have dug into the complexity
of authentication, you're in the cat photo-sharing business, not
the security business.
Let's see if there's an easier way
to delegate some of this complexity to someone else.
SAM OLSEN: Someone else--
like whom?
MALCOLM DECK: Well, Google for starters.
Google has entire teams dedicated
to making sign-in work seamlessly.
Plus, since they own Gmail, Firebase Auth
will automatically trust the email account of any user who
signs in with Google.
SAM OLSEN: Hold on, though.
While I don't wish to denigrate my employer in front
of a large audience, how can you suggest
that their UX is better than what my cat put together
last night?
I mean, look how great it is.
MALCOLM DECK: All the same, I'm sure your app has plenty
of complexity in other ways.
Why spend so much time reinventing the wheel?
Check this out.
We've already talked about how email-link sign-in is related
to email password sign-in.
Well, it turns out that all of the email logins
are just a special case of a generic credential-based
sign-in.
You see, Firebase doesn't actually
care what the underlying type of credential
is, so long as it's valid.
Let's take a look.
In the case of email-password, it's the email-password pair.
You send Firebase an email and password,
and you get back a user.
For email-link, it's the email and
a short-lived out-of-band code embedded
in the link that's sent out.
You send Firebase an email address, and it sends an email.
You then send Firebase the link and the email again,
and Firebase gives you a user.
For providers like Google, the thing you exchange for a user
is an OAuth token, given to us by the Google sign-in flow.
SAM OLSEN: This is starting to make sense.
So Firebase Auth is really just a wrapper
around some of these other types of authentication?
MALCOLM DECK: Yep.
There's a lot that goes into all of this.
But at the end of the day, we're talking about a way
to uniquely and securely identify users.
In the abstract sense, that's what the authentication system
does.
Everything else is just a layer on top of that abstraction.
SAM OLSEN: OK, I'm sold.
Tell me how I'd go about integrating
Google Sign-In into my app.
MALCOLM DECK: Sure thing.
So to briefly reiterate, signing into Firebase
happens in two steps.
One, you get or generate some form of user credential.
Two, you exchange that credential
for a Firebase token.
For email-password, step one is just asking your user
for their email and password.
But for identity providers, that step is just a little bit more
complicated.
SAM OLSEN: Oh, is this where you would use something
like the Google Sign-In SDK?
MALCOLM DECK: Yeah.
How do you know about that?
SAM OLSEN: Oh, I had to use that a long time ago so I
could programmatically upload cat photos to Google Drive.
MALCOLM DECK: Yeah, that sounds about right.
Well, you can use an SDK to get tokens for identity providers,
like Google, Facebook, or Apple, that
have pre-built SDKs for each platform.
Then you can use the OAuth provider class in the Firebase
SDK to package the credentials that you've gotten and call
SignInWithCredential().
SAM OLSEN: Is that it?
Don't I somehow have to let Google and Firebase know
to talk to each other?
MALCOLM DECK: Oh, yeah, good catch.
Before you can use tokens from an identity provider,
you need to go to the Authentication tab
in the Firebase Console, go to the Sign-in Method tab,
and then enable and configure the identity provider.
The configuration is a little different for each provider,
but it should be clear to you what you need.
SAM OLSEN: Is that it?
How do I know how to use the identity provider SDKs?
Do I have to learn a different SDK for each identity
provider I want to support?
MALCOLM DECK: Well, that depends.
The flow we've been talking about so far
is what we call the two-legged OAuth
flow at Firebase, where it has two
distinct steps for developers.
However, we do have a simpler way
to sign in that's the same for all identity providers.
SAM OLSEN: That sounds great.
Why wouldn't you tell me about that first?
MALCOLM DECK: Well, it has pros and cons, depending
on the platform you're on.
If you're just building a web app,
what we're talking about are the signInWithPopup()
and signInWithRedirect() flows.
You'll note that those don't make any use of any SDKs,
other than the Firebase Auth one,
and are the default implementation.
For Android and iOS, we have a feature
we call generic Identity Provider, or IDP, sign in.
It's a way to basically turn all flows into the web redirect
flow on any platform.
But that may mean that the experience is out-of-the-norm
for your users.
It'll be up to you to decide if that means your user's needs.
SAM OLSEN: I can't tell if that's simple or complicated.
How does it work?
MALCOLM DECK: Well, the coding part is relatively simple.
You set up the appropriate secrets in the Firebase Console
and the IDP Console.
On iOS, you set up the appropriate custom URL scheme
and then call the platform-specific sign-in
method.
On Android, that's start activity
for sign in with provider.
And on iOS, it's getCredentialWith().
SAM OLSEN: OK, that doesn't sound so bad.
But what's going on under the hood when everything's set up?
MALCOLM DECK: Ah, so that's a little complicated.
Check out this diagram.
SAM OLSEN: OK, let me fill in the parts I can figure out.
Looks like we start in the app, and the first call
goes out to the browser.
Then what?
MALCOLM DECK: So in the browser, we first go to a page
that Firebase hosts in your project
that we call the Auth Handler.
That page talks to the Firebase backend
to construct the IDP authentication URI
and save some information for the round trip.
SAM OLSEN: OK, and I think I can guess what happens next.
You go to the IDP so the user can sign in.
Oh, and then I bet the IDP uses the redirect URL
that we registered in their console, right?
MALCOLM DECK: Bingo.
And that's the same handler we used earlier.
It marshals the data from the IDP
and uses the information it saved earlier to redirect
to the app.
Once the app receives that data, it calls the Firebase backend
with a credential it got from the IDP
to exchange for a Firebase user.
SAM OLSEN: Just like the flow with the SDK.
Got it.
One last question.
I've heard it's unsafe to pass around credentials
between apps on mobile devices.
I assume we're protected from that?
MALCOLM DECK: Yeah, Firebase uses
a variant of Proof Key for Code Exchange,
called PKCE, a standard scheme for protecting web-based auth
flows on mobile.
In short, yes, your users' credentials are safe.
SAM OLSEN: In my free time, I also maintain
an authentication service that uses uploaded images of cats
instead of passwords.
The pixel data provide a ton of entropy.
Plus, it's just more whimsical than reusing the same password
over and over but slightly altering one letter.
MALCOLM DECK: There is so much wrong with that statement.
But if you have your own auth service,
why are you asking me so many questions about Auth?
SAM OLSEN: I don't know.
Maybe I was testing you.
MALCOLM DECK: Isn't this prerecorded?
I can just look at the answers in my script.
SAM OLSEN: This is getting too meta.
My main question is, I really want
to be able to authenticate my users in my social media app
using my homemade authentication service.
So far, everything you've talked about with Firebase
has seemed very managed.
It doesn't seem like there's room for my cat picture
password process.
MALCOLM DECK: Ah, but there is.
Firebase Auth supports custom authentication.
And when I say custom, I mean just about anything
can be used for authentication.
Remember how we talked about Firebase Auth just
being a wrapper around some form of secure token?
Well, that's exactly what custom auth can be.
Firebase Auth deals in JSON web tokens, known as JWTs,
pronounced "jots."
These underpin every Firebase user,
whether they're signed up with email, phone, Google,
or any other IDP.
Custom auth allows you to put just about anything
in that JSON token, and that will be your user.
This happens in two steps, just like the other auth flows.
One, generate a custom token using your Admin SDK.
Two, exchange that custom token for a user.
SAM OLSEN: Whoa, that seems super powerful.
How is that secure, though?
Couldn't anyone just send in some JSON
and call it their token?
MALCOLM DECK: Good question.
JWTs are more complex than just a JSON string.
They're actually composed of three parts--
a header, a payload, and a signature.
The payload contains interesting things, like custom claims,
last sign-in timestamps, and the user's UID.
The first part, the header, just has some general metadata
so that the consumers know how to interpret the JWT.
The last one, the signature, is the important one
for your question.
The tokens are signed by your Admin SDK service account
credential, meaning that Firebase can distinguish
a valid token from a faked one.
SAM OLSEN: Ah, so next, you're going to tell me
I need my own backend again.
MALCOLM DECK: Well, you'll definitely
need code running the Admin SDK somewhere.
If you want to stay serverless, you
could put this in a cloud function.
Or you could stand up your own server, like you mentioned.
And whatever you do, don't put it
in any code running on a user's device.
But once you've reached that point, custom auth is easy.
One call to this method with any JSON
payload you want will generate a [INAUDIBLE] JWT.
You can return that to your app, and your app
can then sign in with it.
SAM OLSEN: This is really cool.
So how this works for my system is this.
My users sign in by uploading their cat picture password.
My auth system returns a unique ID and some metadata
for that user.
All I have to do is add some function
to my app's backend that creates a JWT with that unique ID,
and I can even put metadata in there?
MALCOLM DECK: Yep.
Like I said, almost anything can go into that JWT payload.
There are special fields that Firebase cares about, like UID.
Then there's the custom claims field, where
you can set extra metadata.
SAM OLSEN: Awesome, but how does that get used?
MALCOLM DECK: Well, for example, in Firebase rules,
you can look at the contents of the JWT
to guard access to Firestore.
SAM OLSEN: Cool.
So now I can guard access to my app's documents
based on how many cats are in the password.
MALCOLM DECK: Sure.
But in reality, this can be used in lots of powerful ways.
Specifying users as having admin powers,
for example, is an excellent use of custom tokens.
SAM OLSEN: These JWTs seem almost too flexible.
How do I know this is a safe way to do things?
MALCOLM DECK: Well, for starters,
JWTs are an industry standard.
Plus, they're signed by a Google service
account tied to your project.
There's no way to create a valid JWT for your app
without going through your own code executing on a runtime you
control.
SAM OLSEN: That makes sense.
So I still need to be diligent about what I do with the JWT
once it's returned to me from the Admin SDK.
Is the entire JWT itself the unique key for the user?
MALCOLM DECK: No.
The UID field is the only one that Firebase uses.
So in your example, if your user changed their password
to have one fewer cat, the next login to Firebase,
the UI would be the same.
But any other fields you set in the custom claims,
like cat count in your example, can change.
SAM OLSEN: This is really cool.
I know realistically, my cat auth service is pretty silly.
And in reality, it's definitely not something
you'd ever want to actually build yourself.
But I can see how you could use custom auth
to integrate with just about any authentication
service you want.
MALCOLM DECK: It's definitely super useful.
While it's not quite "bring your own token to Firebase,"
it's pretty close.
You're not able to log in somewhere else
and talk directly to Firestore, for example.
But by putting one call to createCustomToken() in between,
you effectively have brought that other system's token
to Firebase.
In fact, there's a recent Firebase blog post
by our very own Kevin Chung explaining how to integrate
OCTA into your Firebase app.
SAM OLSEN: Awesome.
Well, this has been super helpful,
though I'm still mad about those email templates.
I know my designer had her heart set on her mocks.
MALCOLM DECK: Happy to help.
I know authentication can seem complicated to navigate,
especially when there are so many different options
to choose from when selecting your sign-in method.
SAM OLSEN: Yeah, the diagram helps a lot.
It seems to me that Firebase Auth is conceptually
just a container around some form
of secure and trusted token.
It all just depends how managed I want the process to be.
MALCOLM DECK: Yep.
You can have any level of involvement you want.
And if you want to do everything yourself,
custom auth is just about as flexible as can be.
SAM OLSEN: Cool.
It's been great chatting with you, Malcolm, and great diving
into some of these more nuanced Auth use cases.
I'm glad I could pick your brain.
MALCOLM DECK: Nice chatting with you too, Sam.
Let me know if your new cat app ever takes off.
SAM OLSEN: Thanks, Malcolm, and thanks to all of you watching.
I hope you've learned a bit about how Firebase Auth works
so that building it into your next app
is that much more seamless.
Bye, folks.
MALCOLM DECK: Bye.
[MUSIC PLAYING]