Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- 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

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.