Authentication

The Simple Blog Example API uses GraphQL over HTTPS to communicate with clients. Any GraphQL client, or even just a plain old HTTP client like fetch can be used to communicate with the API.

Gadget also generates customized JavaScript clients for the Simple Blog Example API which handle authentication automatically. We recommend using these clients where possible. Installation and setup instructions for the Gadget generated clients can be found on the Installing page.

API Key Authentication

The Gadget API uses API Keys to authenticate requests. API keys are secret strings accessible through the Gadget Editor. API Keys grant the holder permissions to read and write different pieces of data depending on which roles the key has been assigned.

API Keys always start with the three letters gsk (standing for Gadget Secret Key), so they look something like gsk-a1z1z1z1z1z1z1z1z11z. Security best practices mandate that you don't commit sensitive data like API keys to your code base, and instead use something like environment variables to pass them to code in production. GitGuardian has a great reference on how to accomplish this.

API Key authentication is useful for server-to-server communication where the client code is trusted, or, for use on the web with a locked down set of permissions. If you're building a server side application that will write data to the Simple Blog Example datastore, API keys are the easiest way to authenticate and limit permissions. If you're building a client side application that will write or read data, you can still use API keys, but you must be careful to limit the permissions a publicly-viewable API key has, as anyone could see it and abuse it.

Browser Session Authentication

Gadget can also use session tokens that represent one user's authentication state with a Gadget application. Clients will receive a private session token representing that one user's browser which refers to one record of the application's Session model. The user can then take actions on their own session like logIn and logOut to change their authorization state. If you are using the Gadget client on your frontend to allow users to log in, you'll want to enable session cookies so that the users can remain logged in and access the resources they are allowed to.

If you're building a client side application where authenticated users should have access to different data than unauthenticated users, then Browser Session Authentication is a great option. Unauthenticated users will have the Unauthenticated role which can allow them to access some data (or none at all), and then once a user logs in, you can grant their roles permission to access more.

Browser Session authentication with Gadget works quite similarly to cookie based authentication in other systems, but Gadget doesn't actually use cookies under the hood in order to make cross-domain authentication work better across different browsers. Instead, Gadget uses the Authorization header to implement a similar scheme, and the generated JavaScript client uses localStorage to store the private session token.

Anonymous Authentication

It can be convenient to allow anyone without an API Key to access data in your application. The Simple Blog Example doesn't strictly require an API Key to be associated with every API request. If the Unauthenticated Role for the application hasn't been granted any permissions however, requests made without an API Key won't be able to read or write any data.

This mode is useful for frontend applications that are just displaying data, like marketing brochures, blogs, or other simple content-based sites. If you don't want to protect access to any data, this is a simple and easy way to get started.

Sending an API Key

If you're using the Gadget JavaScript client for Simple Blog Example , you can pass your API Key as an option to the client when constructing it.

JavaScript
const client = new Gadget({
authenticationMode: { apiKey: "gsk-a1z1z1z1z1z1z1z1z11z" },
});

The client object will automatically pass the API Key to the API for each request it makes.

If you're making requests using some other HTTP client, you must pass the API Key as the token using HTTP Bearer Auth. HTTP requests to the GraphQL endpoint at https://simple-blog-example.gadget.app/api/graphql should use Bearer Token authentication in the headers to do this.

This means passing the HTTP Authorization header with the value Bearer gsk-a1z1z1z1z1z1z1z1z11z, replacing that example API Key with a valid API Key from the Gadget Editor.

For example, you can make an authenticated request with curl by passing the Authorization header.

bash
curl -H "Authorization: Bearer gsk-a1z1z1z1z1z1z1z1z11z" -X POST https://simple-blog-example.gadget.app/api/graphql ...

Enabling Browser Authentication

If you're using the Gadget JavaScript client for Simple Blog Example in a browser context, and you want to allow the user to log in and stay logged in, you can request that the Gadget client track a user's session token with the browserSession: true authentication mode.

JavaScript
const client = new Gadget({ authenticationMode: { browserSession: true } });

Storage modes for session persistence

The JS client has three modes for storing the session token which uniquely identifies the user to allow full configuration of how long a user's session might last. To configure which storage mode is used for session token persistence, pass the storageType option like so:

JavaScript
1import {
2 Client,
3 BrowserSessionStorageType,
4} from "@gadget-client/simple-blog-example";
5const api = new Client({
6 authenticationMode: {
7 browserSession: {
8 storageType: BrowserSessionStorageType.Session,
9 },
10 },
11});

Long lived sessions with BrowserSessionStorageType.Durable (the default)

In this mode, the client will persist the user's session token using window.localStorage. This means the user's session will last generally a long time -- until the user clears local storage or the browser decides it has expired. This option is a good default for applications where users log in and can stay logged in for a long time.

Create a client with durable session token storage
JavaScript
1import {
2 Client,
3 BrowserSessionStorageType,
4} from "@gadget-client/simple-blog-example";
5const api = new Client({
6 authenticationMode: {
7 browserSession: {
8 storageType: BrowserSessionStorageType.Durable,
9 },
10 },
11});

Short term sessions with BrowserSessionStorageType.Session

In this mode, the client will persist the user's session token using window.sessionStorage. This means the user's session will last until they close the tab, which is generally a short time. Users can navigate between pages of the application, or open new tabs and preserve it, but generally sessions stored with BrowserSessionStorageType.Session will be short lived.

This option is a good default for applications where users log in to something very sensitive, or for applications where the user's identity is ephemeral like a browser game or sales chat app.

Create a client with session-length token storage
JavaScript
1import {
2 Client,
3 BrowserSessionStorageType,
4} from "@gadget-client/simple-blog-example";
5const api = new Client({
6 authenticationMode: {
7 browserSession: {
8 storageType: BrowserSessionStorageType.Session,
9 },
10 },
11});

Single page sessions with BrowserSessionStorageType.InMemory

In this mode, the client will not persist the user's session, so it will only last while that one page is active in the user's browser. This means the user's session will last until they navigate away from the page, close the tab, refresh, or do anything to reset the JS context of the page, which is generally a short time.

Create a client with session-length token storage
JavaScript
1import {
2 Client,
3 BrowserSessionStorageType,
4} from "@gadget-client/simple-blog-example";
5const api = new Client({
6 authenticationMode: {
7 browserSession: {
8 storageType: BrowserSessionStorageType.Session,
9 },
10 },
11});

Authentication Failures

If an invalid API Key is passed to Gadget, the API will return an error in the GraphQL error format as a JSON response looking like this.

json
1{
2 "errors": [
3 {
4 "message": "Invalid API Key."
5 }
6 ],
7 "data": null
8}

This error is only returned if an API Key is passed at all. If no Authorization header is sent with the request, which means no API Key has been passed, Gadget treats the request as an anonymous one, and permits or denies access to data using the Unauthenticated Role.