Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Auth JS Setup for Easy OAuth

DavisCCRDavisCCR OS Professional Posts: 8 ✭✭

I am attempting to create an element tab app with Next.js and Auth.js. It seems like it would be easy but no matter what I (or Cursor) try I either run into CSRF errors or invalid requests to the Onshape APIs. I know there is a working example with Passport I just thought it would be cleaner to do it with Auth.js.

This is the auth.ts file I revert back to every time I try something and fail:

// /src/auth.ts
import { OAuthConfig, OAuthUserConfig } from "next-auth/providers";
import NextAuth from "next-auth";
import type { JWT } from "next-auth/jwt";

interface OnshapeProfile {
  id: string
  name: string
  email: string
}

function Onshape(config: OAuthUserConfig<OnshapeProfile>): OAuthConfig<OnshapeProfile> {
  const baseUrl = "https://cad.onshape.com";
  const apiBaseUrl = "https://cad.onshape.com/api/v10";

  return {
    id: "onshape",
    name: "Onshape",
    type: "oauth",
    authorization: {
      url: `${baseUrl}/oauth/authorize`,
      params: { scope: "OAuth2ReadPII OAuth2Read" },
    },
    token: `${baseUrl}/oauth/token`,
    userinfo: {
      url: `${apiBaseUrl}/users/sessioninfo`,
      async request({ tokens, provider }: { tokens: JWT, provider: OAuthConfig<OnshapeProfile> }) {
        const profile = await fetch(provider.userinfo?.url as URL, {
          headers: {
            Authorization: `Bearer ${tokens.access_token}`,
            "User-Agent": "authjs",
          },
        }).then(async (res) => await res.json())
        return profile
      },
    },
    profile(profile) {
      return {
        id: profile.id,
        name: profile.name,
        email: profile.email,
      }
    },
    options: config,
  }
}

export const { handlers, auth } = NextAuth({
  debug: true,
  providers: [Onshape({
    clientId: process.env.AUTH_ONSHAPE_ID,
    clientSecret: process.env.AUTH_ONSHAPE_SECRET,
  })],
  callbacks: {
    authorized: async ({ auth }) => {
      return !!auth
    },
  },
});

I have tried giving Cursor the passport examples and telling it to replicate the behavior in the callback functions but had no luck.

I have experimented with the middleware a bunch but right now it is just:

// /src/middleware.ts
export { auth as middleware } from "@/auth";

This is my OAuth setup in the developer portal:

Redirect URL: https://localhost:3000/api/auth/callback/onshape

OAuth URL: https://localhost:3000/api/auth/signin/onshape

I am running it locally with a self signed certificate but I get the same errors when hosting in on Vercel.

If anyone has solved this or knows how to then I could make a pull request to add it to the built in providers of Auth.js.

Sign In or Register to comment.