Authentication

The alida-quiz-app-2 API uses GraphQL over HTTPS to communicate with clients. Purpose-built GraphQL clients as well as HTTP clients like fetch, cURL, or the HTTP library for your programming language of choice can be used to communicate with your app's Gadget API.

Gadget generates a JavaScript client for the alida-quiz-app-2 API which handles 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.

Authentication modes

The Gadget API supports three different authentication modes:

ModeDescriptionUse cases
Browser Session authenticationGadget stores a session token (similar to a cookie) in the user's browser, and sends it in the Authorization headerClient-side applications, browser single sign-on, user login/logout flows
Anonymous authenticationNo authentication header sent at allPublicly accessible data, e-commerce storefronts
API Key authenticationCopy a gsk-xxxxxx API Key from the API Keys page in the editor, and pass it in the Authorization headerServer-to-server communication, bots, scripts
Shopify Session TokenAuth managed by Shopify's session tokens and [@gadgetinc/react-shopify-app-bridge]Apps embedded in the Shopify admin

The API client will use Browser Session authentication by default if it detects that it's running in a browser environment, and use Anonymous authentication by default if not running in a browser.

Browser Session Authentication

Gadget can use session tokens to authenticate individual users to the backend. Session tokens work similarly to cookies. Clients will receive a private session token representing that one client's browser, and the token will be represented in the backend by one record of the application's Session model. The client can then run Actions on this session record to change their authorization state.

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, they can be given a role with different permissions.

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 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.

Read more about implementing roles and permissions for your app in the Access Control guide.

Enabling Browser Authentication

If you're using the Gadget JavaScript client for alida-quiz-app-2 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
1import { Client } from "@gadget-client/alida-quiz-app-2";
2const client = new Client({
3 authenticationMode: {
4 browserSession: true,
5 },
6});

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 { Client, BrowserSessionStorageType } from "@gadget-client/alida-quiz-app-2";
2const api = new Client({
3 authenticationMode: {
4 browserSession: {
5 storageType: BrowserSessionStorageType.Session,
6 },
7 },
8});

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 { Client, BrowserSessionStorageType } from "@gadget-client/alida-quiz-app-2";
2const api = new Client({
3 authenticationMode: {
4 browserSession: {
5 storageType: BrowserSessionStorageType.Durable,
6 },
7 },
8});

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 { Client, BrowserSessionStorageType } from "@gadget-client/alida-quiz-app-2";
2const api = new Client({
3 authenticationMode: {
4 browserSession: {
5 storageType: BrowserSessionStorageType.Session,
6 },
7 },
8});

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 { Client, BrowserSessionStorageType } from "@gadget-client/alida-quiz-app-2";
2const api = new Client({
3 authenticationMode: {
4 browserSession: {
5 storageType: BrowserSessionStorageType.Session,
6 },
7 },
8});

Anonymous Authentication

It can be convenient to allow anyone without an API Key to access some data in your application. For example, anyone on the internet should be able to visit a blog and read the posts, or visit an e-commerce storefront and view the products, so no authentication is needed for this kind of data.

To use Anonymous authentication, make requests without sending an API key or a browser session token. Requests to the alida-quiz-app-2 app without any authentication information will be assigned the Unauthenticated role. The Gadget application developer will need to grant the Unauthenticated role permission to access this publically-available data. If the Unauthenticated Role for the application hasn't been granted any permissions, requests made without an API Key won't be able to read or write any data.

To create a client that uses no authentication, pass anonymous: true to the authenticationMode option when creating the client:

JavaScript
1import { Client } from "@gadget-client/alida-quiz-app-2";
2const client = new Client({
3 authenticationMode: {
4 anonymous: true,
5 },
6});

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 like so:

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.

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 permission 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.

Don't send API keys to the browser as they can be read from the source code and used for malicious purposes.

API Key authentication is useful for server-to-server communication where the client code is trusted.

If you're building a server-side application that will write data to the alida-quiz-app-2 datastore, API keys are the easiest way to authenticate and limit permissions.

Sending an API Key

If you're using the Gadget JavaScript client for alida-quiz-app-2, 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://alida-quiz-app-2--development.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://alida-quiz-app-2--development.gadget.app/api/graphql ...