Skip to Content

Configuring WunderGraph Authentication

Published: September 09, 2021

WunderGraph comes with Authentication support out of the box. We're currently supporting OpenID Connect as auth provider. This allows you very easily to add authentication directly via GitHub, Google, etc... or through an OIDC Relaying Party (RP) like e.g. Auth0, Okta or Keycloak.

In case of a direct integration with e.g. Google OAuth2, the WunderGraph Server (WunderNode) will redirect the user to the Google login page and handle the login flow.

If you're using a OIDC RP like Auth0, the WunderGraph Server will redirect to the RP which will then handle the login flow. Once the RP is successful, the RP will redirect back to the WunderGraph Server which will finish the initial login flow.

Concepts#

Currently, WunderGraph supports cookie-based Authentication. This means, the complete login flow is handled server-side. For that reason, we don't implement PKCE as it doesn't add any additional value. Instead, we're using standard best practices for server-side OIDC clients. This means, we're creating a short-lived state cookie.

We've chosen to use Cookie-Based Authentication as the default for web applications as it makes the implementation in the client very easy. Additionally, it's the only Authentication mechanism in the web that makes Server-Side rendering for authenticated users possible.

CSRF Protection out of the box#

For those familiar with OWASP, it'll be obvious that cookie-based authentication makes CSRF attacks possible. For that reason, we've built CSRF protection natively into WunderGraph. Each mutating API endpoint is automatically CSRF protected. Additionally, all generated WunderGraph clients will transparently handle the required steps to handle the CSRF protection flows.

As a user of WunderGraph, you don't have to do anything to enable this, it's the default, and you're not able to disable it. We're taking security seriously while we don't want to compromise on the user experience.

Configuring WunderGraph Authentication Providers#

Configuring Authentication providers is very much straight forward.

Creating a OIDC/OAuth2 Client#

To be able to configure an authentication provider, you first have to create a client. You need a few infos to be able to do this.

First, you have to know the URI(s) which your WunderGraph Server (WunderNode) is operating on. Keep in mind that the login flow is handled server-side. This means, the login URI is the WunderNode, not your web application.

The default listen path on your local machine is localhost:9991. If you run wunderctl up with the default configuration, the login URI will be http://localhost:9991.

Additionally, you have to configure the Callback URI. This Callback URI is required to finish the login flow. Once the OpenID Connect / OAuth2 provider has successfully done the login flow, it will redirect the user to this URI.

The template for the Callback URI looks like this:

http://localhost:9991/%API_NAME%/%ENVIRONMENT_NAME%/auth/cookie/callback/%AUTHENTICATION_PROVIDER_ID%

By default, the domain will be localhost:9991. API_NAME is "app" by default. ENVIRONMENT_NAME is "main" if not otherwise specified. AUTHENTICATION_PROVIDER_ID is the ID you've chosen for your Authentication Provider.

The default callback URI for an Authentication Provider with the id "google" will look like this:

http://localhost:9991/api/main/auth/cookie/callback/google

Configuring the Authentication Provider#

Once you have created your OIDC/OAuth2 client, you're ready to configure is in your wundergraph.config.ts.

configureWunderGraphApplication({
...
authentication: {
cookieBased: {
providers: [
authProviders.demo(),
authProviders.github({
id: "github", // you have to choose this ID
clientId: "XXX", // client ID from GitHub
clientSecret: "XXX" // client secret from GitHub
}),
authProviders.google({
id: "google", // you have to choose this ID
clientId: "XXX.apps.googleusercontent.com", // client ID from Google
clientSecret: "XXX" // client secret from Google
}),
authProviders.oidc({
id: "auth0", // you have to choose this ID
clientId: "XXX", // client ID from Auth0
clientSecret: "XXX" // client secret from Auth0
}),
authProviders.oidc({
id: "okta", // you have to choose this ID
clientId: "XXX", // client ID from Okta
clientSecret: "XXX" // client secret from Okta
}),
]
}
},
});

Using the configured Authentication Provider in your Application#

Let's assume, you've created a WunderGraph Application using NextJS. You've configured two Authentication Providers with the following IDs: github, google

The two Authentication Provider IDs will be used to generate a type-safe client for you which handles authentication automatically. The way you'd make use of them looks like this:

const Demo: NextPage = () => {
const {user, client: {login}} = useWunderGraph();
return (
<div>
<p>{JSON.stringify(user || "not authenticated")}</p>
<button onClick={() => login.github()}>Login With GitHub</button>
<button onClick={() => login.google()}>Login With Google</button>
</div>
)
}

As you can see, the "client" object returned by "useWunderGraph" has a "login" object. This "login" object contains two functions to initiate the login flow. The function names map exactly to the IDs of the Authentication Providers you've configured.

Considerations for Staging & Production#

So far, we've used localhost:9991 as the base for the login- and callback URI. This works well for local development. However, how about running in staging or production?

Some Authentication Providers like Google allow you to configure multiple login and callback URIs. Others, like GitHub, only allow you to configure one single callback URI.

In general, you should not use the same login credentials across different stages (dev,prod). Ideally, you'd create one client per stage and configure it via the environment. This means, you'll extract clientID and secret into environment variables. Then, depending on the stage you're deploying to, you'll inject the correct client credentials.

For example, if your production environment runs on myapp.wundergraph.dev and you've configured one single authentication provider with the ID myprovider with defaults for api name (api) and environment (main), the login URI and Callback URI will look like this:

Login: https://myapp.wundergraph.dev.

Callback: https://myapp.wundergraph.dev/api/main/auth/cookie/callback/google


Product

Subscribe to our newsletter!

Stay informed when great things happen! Get the latest news about APIs, GraphQL and more straight into your mailbox.

© 2021 WunderGraph