# Using Google OAuth with MongoDB for User Authentication

- Canonical: https://33rdsquare.com/google-oauth-for-mongodb-user-authentication-sign-in/
- Published: 2024-09-03
- Author: Jordan Brown
- Categories: [Artificial Intelligence & Machine Learning & ChatGPT](https://33rdsquare.com/category/tech/ai/)

---

Web application security is paramount in today‘s world of data breaches and privacy regulations. One critical aspect is authentication – ensuring only authorized users can access protected resources. While you can implement your own user management, it‘s often preferable to delegate this responsibility to a trusted third-party identity provider.

In this article, we‘ll walk through integrating Google Sign-In with a Node.js web app that uses MongoDB for its database. By the end, you‘ll have a working sample that lets users log in with Google to access protected routes powered by MongoDB. We‘ll also cover some security best practices and touch on alternative approaches to consider.

## Overview of Google OAuth Flow

OAuth 2.0 is an industry-standard protocol for authorization. It allows a user to grant limited access to their resources on one site (the service provider), to another site (the consumer), without sharing their credentials.

Google OAuth is Google‘s implementation of OAuth 2.0. From an application‘s perspective, it provides a secure way to access Google APIs on behalf of a user. But it can also be used for general user authentication.

Here‘s a simplified overview of the flow:

1. The user clicks "Sign in with Google" in the app
2. The app redirects them to Google, along with info on what permissions it requires
3. The user authenticates with Google and grants the app permission
4. Google redirects the user back to the app with an authorization code
5. The app exchanges the authorization code for access and ID tokens
6. The ID token can be used to establish the user‘s identity, while the access token lets the app access Google APIs on their behalf

The actual flow has a few more steps, but this captures the gist of it. The key point is the app never sees the user‘s Google password. It receives tokens that it can use to identify the user and access APIs.

## Benefits of Federated Login

There are several advantages to using a third-party identity provider like Google:

1. Improved user experience. Users can sign in with an existing account rather than creating yet another username/password.
2. Enhanced security. Google invests heavily in security and likely has more robust protections than what you would build in-house. Outsourcing authentication shifts a big chunk of the security burden and risk.
3. Reduced development effort. Not having to build your own login forms, user management screens, password reset flows, etc. can significantly speed up development.
4. Access to additional data. The ID token contains basic info like the user‘s name and email that you can use to pre-fill forms or personalize the UX. You can also request access to things like the user‘s contacts or Google Drive.

That said, there are tradeoffs. You are introducing a dependency on a third-party service. If Google is down, users won‘t be able to log into your app. There are also privacy considerations, as you are sharing some user data with Google.

But for most applications, using a mainstream identity provider is a net win. It‘s the approach we‘ll use here.

## Setting up Google OAuth

The first step is to create a new Google API Console project:

1. Go to [https://console.developers.google.com/apis/dashboard](https://console.developers.google.com/apis/dashboard)
2. Click "Create Project" and enter a name
3. Select the project, then go to "Credentials" in the sidebar
4. Click "Create Credentials" and select "OAuth client ID"
5. Choose "Web application"
6. Give it a name, then enter the authorized redirect URI, e.g. [https://myapp.com/auth/google/callback](https://myapp.com/auth/google/callback)
7. Click "Create" to get your client ID and secret

Make a note of the client ID and secret, as you‘ll need them later to configure your app.

## Adding Google Sign-In to Node.js App

There are several Node.js libraries that wrap the Google OAuth flow. Here we‘ll use Passport.js.

First install the dependencies:

```
npm install passport passport-google-oauth20
```

Then configure Passport with your Google client ID and secret:

```
const passport = require(‘passport‘);
const GoogleStrategy = require(‘passport-google-oauth20‘).Strategy;

passport.use(new GoogleStrategy({
    clientID: GOOGLE_CLIENT_ID,
    clientSecret: GOOGLE_CLIENT_SECRET,
    callbackURL: "https://myapp.com/auth/google/callback"
  },
  function(accessToken, refreshToken, profile, cb) {
    // Here, you would typically check if the user exists in your DB
    // and create a new record if they don‘t
    console.log(profile);
    cb(null, profile);
  }
));
```

This tells Passport to use the GoogleStrategy and provides the OAuth client settings. The function is called after the user authenticates with Google. It receives the access token, a refresh token (used to get a new access token if it expires), and a profile containing the user‘s basic info.

You would typically use the data in `profile` to check if the user already exists in your database, and if not, create a new record for them. The `cb` function is called to complete the authentication process.

To initiate the Google flow, send the user to the following URL:

```
https://myapp.com/auth/google
```

Set up a route to handle this URL:

```
app.get(‘/auth/google‘, passport.authenticate(‘google‘, { scope: [‘profile‘, ‘email‘] }));
```

The `scope` specifies what access the app requires. Here, it is requesting read-only access to the user‘s profile and email.

Finally, create a route to handle the callback:

```
app.get(‘/auth/google/callback‘,
  passport.authenticate(‘google‘, { failureRedirect: ‘/login‘ }),
  function(req, res) {
    res.redirect(‘/‘);
  });
```

After the user grants permission, Google will redirect back to this URL, sending an authorization code. Passport will exchange this for access and ID tokens, then call the function passed to `GoogleStrategy` above.

The ID token is a JWT that contains basic info about the user, signed by Google. You should always [verify the token](https://developers.google.com/identity/sign-in/web/backend-auth) on the backend to ensure it hasn‘t been tampered with.

The access and refresh tokens let your app access Google APIs on behalf of the user. If your app doesn‘t need Google API access, you can skip requesting these by setting `accessType: ‘offline‘` in the `GoogleStrategy` options.

## Integrating MongoDB

To use the Google OAuth token for MongoDB authentication, you need to pass it when connecting to the database. MongoDB lets you authenticate using external auth mechanisms like OAuth or SAML.

First enable OAuth authentication for your MongoDB cluster:

1. Log into the MongoDB Atlas console
2. Go to "Clusters" and select "Connect"
3. Click "Connect your application"
4. Select "Other" as the driver
5. Copy the connection string

It should look something like:

```
mongodb+srv://<username>:<password>@cluster0.abc123.mongodb.net/mydb?authSource=%24external&authMechanism=MONGODB-AWS
```

In your Node.js app, construct the connection string:

```
const MongoClient = require(‘mongodb‘).MongoClient;

const uri = "mongodb+srv://<username>:<password>@cluster0.abc123.mongodb.net/mydb?authSource=%24external&authMechanism=MONGODB-X509&retryWrites=true&w=majority";

const clientCert = `
-----BEGIN CERTIFICATE-----
${googleIdToken}
-----END CERTIFICATE-----`

const client = new MongoClient(uri, {
  sslKey: clientCert,
  sslCert: clientCert
});

client.connect(err => {
  // ...
});
```

Here, we are using the `MONGODB-X509` auth mechanism which allows authentication using an X.509 certificate. We pass the Google ID token (a JWT) as the certificate.

On the MongoDB side, the ID token will be validated and the user‘s identity established based on the `sub` (subject) claim, which uniquely identifies the user.

## Security Considerations

When implementing OAuth authentication, there are a few key things to keep in mind:

1. Always validate tokens on the backend. Don‘t rely on any checks done on the client side.
2. Use HTTPS everywhere. OAuth relies heavily on redirects, which can be exploited if sent over unencrypted HTTP.
3. Don‘t store tokens in local storage or cookies. Store them server-side and associate them with the user‘s session.
4. Limit requested scopes. Only request access to the resources your app actually needs. Avoid asking for broad permissions like access to the user‘s entire Google Drive.
5. Use refresh tokens securely. Refresh tokens have a long lifetime and let you get new access tokens. Treat them like passwords and never expose them to the client.
6. Keep secrets safe. Don‘t commit your OAuth client secret to source control. Use environment variables or a secrets manager.

By following these best practices, you can reduce the risk of leaking user data and limit the blast radius if an attacker does gain access to tokens.

## Alternative Approaches

While OAuth is a popular choice for authentication, it‘s not the only option. Some alternatives to consider:

- OpenID Connect (OIDC): An authentication layer built on top of OAuth 2.0. It standardizes things like scopes and token formats to make OAuth easier to use for authentication.
- SAML: An XML-based standard for exchanging authentication and authorization data. Typically used in enterprise scenarios for single sign-on (SSO).
- Passwordless auth: Lets users sign in using a magic link sent to their email or a code sent via SMS. Avoids the need for passwords altogether.
- Social login: Similar to the Google example here, but using other social providers like Facebook, Twitter, GitHub, etc. Usually done via OAuth, but each provider has its own quirks.
- Traditional username/password: The tried-and-true approach. Not as user-friendly as the options above, but gives you complete control over the UX and user data.

The "right" choice depends on your specific requirements. For most consumer apps, using one or more OAuth providers is a good default. You can always support additional options down the road.

## Conclusion

In this article, we‘ve explored how to use Google OAuth to authenticate users and integrate with MongoDB. The key steps are:

1. Create a Google API Console project and OAuth credentials
2. Configure an OAuth library like Passport.js in your backend
3. Initiate the OAuth flow by redirecting the user to Google
4. Handle the OAuth callback and retrieve tokens
5. Pass the ID token when connecting to MongoDB

By leveraging a trusted identity provider, you can speed up development, provide a better UX, and reduce security risks. While there are tradeoffs to consider, for most applications it‘s a net win.

The code samples here focused on Node.js and MongoDB, but the general flow is similar for other languages and databases. Adapt it to your stack of choice.

Hopefully this has been a helpful introduction to authentication with Google and MongoDB. Check out the additional resources below to dive deeper. As always, feel free to reach out with any questions!

Additional Resources

- [Google OAuth Documentation](https://developers.google.com/identity/protocols/oauth2)
- [MongoDB External Authentication](https://docs.mongodb.com/manual/core/security-external-auth/)
- [Passport.js OAuth Guide](http://www.passportjs.org/docs/oauth/)

---

Source: [Using Google OAuth with MongoDB for User Authentication](https://33rdsquare.com/google-oauth-for-mongodb-user-authentication-sign-in/)
