
Does account.createOAuth2Token
handle GitHub apps (this is not a GitHub OAuth app)? I'm using NextJS 15 and appwrite-node
SDK and testing in local environment. So origin
should be something like http://localhost:3000
In my login page I have a button Continue with GitHub where the user is redirected to this route:
import { NextRequest } from 'next/server';
import { adminClient } from '@/lib/server/appwrite';
import { OAuthProvider } from 'node-appwrite';
export async function GET(request: NextRequest) {
try {
const origin = process.env.NEXT_PUBLIC_APP_URL!;
if (!origin) {
throw new Error('NEXT_PUBLIC_APP_URL environment variable is required');
}
const { account } = await adminClient();
const redirectUrl = await account.createOAuth2Token(
OAuthProvider.Github,
`${origin}/auth`,
`${origin}/login?error=github_auth_cancelled`,
['repo', 'user', 'issues:write']
);
return Response.redirect(redirectUrl, 302);
}
catch (error) {
console.error('GitHub auth error:', error);
if (error instanceof Error) {
console.error('Error details:', {
message: error.message,
name: error.name,
stack: error.stack,
});
}
return Response.redirect(`${origin}/login?error=github_auth_failed`, 302);
}
}
This is the ERROR I get:
{"message":"There was an error processing your request. Please check the inputs and try again.","code":400,"type":"general_bad_request","version":"1.6.1"}
Would be nice to have some logs in the dashboard

The success route looks like this:
import { adminClient } from '@/lib/server/appwrite';
import { cookieSave } from '@/lib/server/cookies';
import { redirect } from 'next/navigation';
import { NextRequest, NextResponse } from 'next/server';
export const GET = async (request: NextRequest) => {
try {
const { searchParams } = request.nextUrl;
const userId = searchParams.get('userId');
const secret = searchParams.get('secret');
const { account } = await adminClient();
if(!userId || !secret) {
return redirect(`${process.env.NEXT_PUBLIC_APP_URL!}/signup`)
}
const session = await account.createSession(userId, secret);
const cookieSaved = await cookieSave(session.secret);
const tokenCookieSaved = await cookieSave(secret, `${process.env.NEXT_PUBLIC_COOKIE_SESSION_NAME!}_token`);
const sessionCookie = cookieSaved.toString();
const tokenCookie = tokenCookieSaved.toString();
return new Response(
`<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${process.env.NEXT_PUBLIC_APP_URL}/app"></head></html>`,
{
headers: {
'Content-Type': 'text/html',
'Set-Cookie': `${sessionCookie}, ${tokenCookie}`,
},
}
);
} catch (error) {
console.error('Auth error:', error);
return NextResponse.redirect(`${process.env.NEXT_PUBLIC_APP_URL}/error`);
}
};

And this is my appwrite setup:
'use server';
import { Client, Account, Databases } from 'node-appwrite';
import { cookieGet } from './cookies';
import { cache } from 'react';
// For middleware only
export const createSessionClient = async () => {
const client = new Client()
.setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT!)
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID!)
const session = await cookieGet();
if (!session?.value) {
throw new Error('No session');
}
client.setSession(session.value);
return new Account(client);
};
export const sessionClient = cache(async () => {
const client = new Client()
.setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT!)
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID!)
const session = await cookieGet();
if (!session?.value) {
throw new Error('No session');
}
client.setSession(session.value);
return {
get account() {
return new Account(client);
}
};
});
export const adminClient = async () => {
const client = new Client()
.setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT!)
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID!)
.setKey(process.env.APPWRITE_API_KEY!);
return {
get databases() {
return new Databases(client)
},
get account() {
return new Account(client);
},
};
};
export const getLoggedInUser = async () => {
try {
const { account } = await sessionClient();
return await account.get();
}
catch (error) {
console.error(error);
return null;
}
};
Recommended threads
- Clarification on Fixing a Frontend Bug R...
Hey everyone! My group and I are working on this issue (#8976) as part of an open-source project, and we came across a frontend bug. However, the issue was orig...
- HIPAA Compliance only on Scale plan?
Dear Appwriters, why are HIPAA, BAA and SOC-2 only checked for the 'Scale' plan? Does this mean when using the 'Pro' Plan that my data is not compliant with the...
- The maximum number or size of attributes...
is there a limit to number of attributes in a collection ? what is it ? Can it be increased ? What is the workaround ?
