Logo

dev-resources.site

for different kinds of informations.

Umbraco and Bellissima: Swagger, Tokens, Entry Points

Published at
12/18/2024
Categories
umbraco
webdev
javascript
oauth
Author
iovergaard
Categories
4 categories in total
umbraco
open
webdev
open
javascript
open
oauth
open
Author
10 person written this
iovergaard
open
Umbraco and Bellissima: Swagger, Tokens, Entry Points

These examples are meant to set up authentication in your own code in Umbraco 14+ by hooking on to the authorization mechanism of Umbraco to extract the access_token.

The following examples are tested in Umbraco 14 and 15 and I have written them here mostly to be able to quickly look up how to get started with an entry point to the Umbraco Backoffice.

Basic authentication

What we are trying to achieve is essentially to get the token to use in the Authorization header in a fetch() call:

fetch('/myapi/controller/endpoint', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer 123' // <-- Token goes here
  }
});
Enter fullscreen mode Exit fullscreen mode

This can be wrapped in Umbraco using the Context API:

/**
 * Make an authorized request to any Backoffice API.
 * @param host A reference to the host element that can request a context.
 * @param url The URL to request.
 * @param method The HTTP method to use.
 * @param body The body to send with the request (if any).
 * @returns The response from the request as JSON.
 */
async function makeRequest(host: UmbClassInterface, url: string, method = 'GET', body?: any) {
  const authContext = await host.getContext(UMB_AUTH_CONTEXT);
  const token = await authContext.getLatestToken();
  const response = await fetch(url, {
    method,
    body: body ? JSON.stringify(body) : undefined,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`,
    },
  });
  return response.json();
}
Enter fullscreen mode Exit fullscreen mode

Don't do this, though. Use a TypeScript client generator instead:

TypeScript Client

I always use the latest version of @hey-api/openapi-ts to generate the TypeScript client. This library supports several clients including their own @hey-api/client-fetch that wraps the native fetch client. The generator can also use the native Fetch API directly using the native/fetch library. Here is how to hook on to Umbraco's authentication for both clients:

First, install @hey-api/openapi-ts:

npm i --save @hey-api/openapi-ts @hey-api/client-fetch
Enter fullscreen mode Exit fullscreen mode

Then create a script in package.json:

{
  "scripts": {
    "generate": "openapi-ts -i http://localhost:7029/umbraco/swagger/bellissima-v1/swagger.json?urls.primaryName=Bellissima%20Management%20Api -o src/api -c @hey-api/client-fetch"
  }
}
Enter fullscreen mode Exit fullscreen mode

Next, create /App_Plugins/MyExtensions/umbraco-package.json and register an extension of the type backofficeEntryPoint:

{
  "name": "My Extensions",
  "alias": "My.Extensions",
  "version": "1.0.0",
  "extensions": [
    {
      "type": "backofficeEntryPoint",
      "alias": "My.Entrypoint",
      "name": "My Entrypoint",
      "js": "/App_Plugins/MyExtensions/entry-point.js"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Make sure to set up a TypeScript transpiler (tsc, vite, etc) and create an entry-point.ts file.

@hey-api/client-fetch

Add the following to entry-point.ts:

import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api';
import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth';
import { client } from './api/index.js';

export const onInit: UmbEntryPointOnInit = (host) => {
  host.consumeContext(UMB_AUTH_CONTEXT, (authContext) => {

    // Get API config
    const config = authContext.getOpenApiConfiguration();

    // Set base config
    client.setConfig({
      baseUrl: config.base,
      credentials: config.credentials
    });

    // Set interceptor to add authorization
    client.interceptors.request.use(async (req) => {
      const token = await config.token();
      if (token) {
        req.headers.set('Authorization', `Bearer ${token}`);
      }
      return req;
    });
  });
};
Enter fullscreen mode Exit fullscreen mode

legacy/fetch

Note: This client is deprecated. To use it, replace @hey-api/client-fetch with legacy/fetch in the generate script.

Add the following to entry-point.ts:

import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api';
import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth';
import { OpenAPI } from './api/index.js';

export const onInit: UmbEntryPointOnInit = (host) => {
  host.consumeContext(UMB_AUTH_CONTEXT, (authContext) => {

    // Get API config
    const config = authContext.getOpenApiConfiguration();

    // Set base config
    OpenAPI.BASE = config.base;
    OpenAPI.TOKEN = config.token;
    OpenAPI.CREDENTIALS = config.credentials;
    OpenAPI.WITH_CREDENTIALS = config.withCredentials;
    OpenAPI.ENCODE_PATH = config.encodePath;
  });
};
Enter fullscreen mode Exit fullscreen mode

The entry point ensures authorization is set up before any requests are made in the Backoffice, and you can now import the generated SDK and call it from any element with or without the tryExecute and tryExecuteAndNotify functions.

What's Next

Now you have an entry point to the Backoffice set up with authentication from Umbraco into your API. From here, you can register any kind of extension you want using the extensionRegistry argument on the onInit method. Expand onInit with the following:

export const onInit: UmbEntryPointOnInit = (host, extensionRegistry) => {
  extensionRegistry.register({
    type: 'X'
  });
};
Enter fullscreen mode Exit fullscreen mode

Replace X with whatever type you want to register. The full list is available on the UmbracoDocs.

Happy hacking.

oauth Article's
30 articles in total
Favicon
Are millions of accounts vulnerable due to Google's OAuth Flaw?
Favicon
Pushed Authorization Requests in .NET 9: Why and How to Use Them
Favicon
Understanding OAuth 1.0a Signature Generation: Postman vs. Node.js Library and Custom Implementation
Favicon
A Comprehensive Guide to Using OAuth 1.0a with Twitter API v2
Favicon
Understanding Twitter API OAuth 1.0a Authentication: A Comprehensive Guide
Favicon
Spring Oauth2 - App-Token based Hybrid Token Verification Methods
Favicon
App-Token based easy OAuth2 implementation built to grow with Spring Boot
Favicon
Accessing the AuthAction Management API with Machine-to-Machine Application
Favicon
How to oAuth2 Code Flow using Tanstack Start
Favicon
Serverless OAuth2/OIDC server with OpenIddict 6 and RDS Aurora v2
Favicon
Getting Started with Keycloak: Understanding the Basics
Favicon
Finalmente entendi o OAuth
Favicon
Login with Google, Laravel 11
Favicon
Integrating Google OAuth 2.0 with JWT in a Node.js + TypeScript App using Passport.js
Favicon
OAuth2 Authentication API
Favicon
.NET MAUI Google Drive OAuth on Windows and Android
Favicon
Extortion Pack
Favicon
Umbraco and Bellissima: Swagger, Tokens, Entry Points
Favicon
MS Graph API Certificate and Client Secret OAuth2.0 in Java Spring boot
Favicon
Securing Spring Microservice with OAuth 2.0
Favicon
OAuth2, JWT, and JWKS: Using Amazon Cognito as IDP
Favicon
Mission impossible with localhost
Favicon
React Oauth2 Integration with AuthAction
Favicon
Harness Authentication Capabilities
Favicon
🔐 How to Implement OAuth 2.0 Authentication in ASP.NET Core with External APIs
Favicon
Vuejs Oauth2 Integration with AuthAction
Favicon
Angular Oauth2 Integration with AuthAction
Favicon
Google identity Platform
Favicon
How to Secure Your AWS EKS Application with OAuth 2.0 and SSO Integration Using Amazon Cognito and OAuth2-Proxy
Favicon
OAuth Tutorial with Go and the Spotify API

Featured ones: