Quickstart
Connect your app to Campus One and sign in a test user in a few minutes
This is the fastest path from zero to seamless sign-in. It uses OpenID Connect — the live SSO protocol — and a library that auto-configures from our discovery URL, so you write very little code.
[!IMPORTANT] Don't build a login page. Campus One is the login experience. Your app should never render its own email/password, signup, or password-reset screens — instead it redirects unauthenticated visitors straight to Campus One, and because the student already has a Campus One session, they come back signed in without typing anything. See Seamless single sign-on below.
[!TIP] Already know OIDC? You only need three things: the discovery URL
https://auth.campusone.com.ng/api/auth/.well-known/openid-configuration, your Client ID, and your Client Secret. Point any OIDC library at them and you're done. The rest of this page walks through it.
Before you start
You need a developer account. An admin invites you (you'll get a link to set your password), then you sign in to the developer dashboard at https://app.campusone.com.ng/developer/apps. See Application Management for the full dashboard tour.
Register your app
In the developer dashboard, click Connect new app and complete the wizard:
- Protocol: OIDC
- Redirect URL: where Campus One sends users back after login — e.g.
http://localhost:3000/api/auth/callback/campus-onefor local development. You can add production URLs later. - Scopes: start with
profileandemail; addacademic,notifications,events, orrolesif you need them (see Permissions).
[!NOTE] Apps work immediately in
Pendingstatus — you do not need admin approval to start testing OIDC sign-in, consent, and token issuance.
Copy your credentials
Open your app → Sign-in tab and copy:
CAMPUS_ONE_CLIENT_ID="…" # shown at the top of the tab
CAMPUS_ONE_CLIENT_SECRET="…" # click "Reveal" — shown once; rotate if lostKeep the secret server-side. Never ship it in a client bundle or commit it.
Wire up an OIDC client
Point your framework's OIDC support at the discovery URL. Two common setups:
// Auth.js / NextAuth — app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
export const { handlers, auth } = NextAuth({
providers: [
{
id: "campus-one",
name: "Campus One",
type: "oidc",
issuer: "https://auth.campusone.com.ng",
wellKnown:
"https://auth.campusone.com.ng/api/auth/.well-known/openid-configuration",
clientId: process.env.CAMPUS_ONE_CLIENT_ID,
clientSecret: process.env.CAMPUS_ONE_CLIENT_SECRET,
authorization: { params: { scope: "openid profile email academic" } },
},
],
});// Better Auth (consumer side)
import { betterAuth } from "better-auth";
import { genericOAuth } from "better-auth/plugins/generic-oauth";
export const auth = betterAuth({
plugins: [
genericOAuth({
config: [
{
providerId: "campus-one",
discoveryUrl:
"https://auth.campusone.com.ng/api/auth/.well-known/openid-configuration",
clientId: process.env.CAMPUS_ONE_CLIENT_ID!,
clientSecret: process.env.CAMPUS_ONE_CLIENT_SECRET!,
scopes: ["openid", "profile", "email", "academic"],
pkce: true, // required
},
],
}),
],
});PKCE is required on all clients. Mainstream libraries handle it automatically; if you're rolling your own flow, follow the OIDC guide.
Auto-redirect unauthenticated users (no login page)
Instead of a login screen, guard your protected routes: when there's no local session, immediately start the OIDC redirect. The student is bounced to Campus One and — if they already have a Campus One session — straight back to your app, signed in, with nothing to type.
// Example: middleware / route guard (pseudo-code, framework-agnostic)
export function middleware(request) {
const session = getLocalSession(request);
if (!session) {
// No app-side login UI — kick off the OIDC flow right here.
return redirectToCampusOne(request.url); // -> /api/auth/signin/campus-one
}
}For the rare signed-out entry point (e.g. a public marketing page with a "Go to dashboard" action), a single redirect link is all you need — never a form:
<a href="/api/auth/signin/campus-one">Continue with Campus One</a>After login your app receives an ID token containing the user's identity — sub, email, name, role, and (with the academic scope) student_id, level, faculty_id, department_id. Use the top-level role claim for authorization without an extra request. Full claim list: OIDC claims.
Seamless single sign-on (no login page)
The whole point of Campus One is that students sign in once. When they open your connected app, they shouldn't see a login form or re-enter credentials — they should just be in. Here's how to get that:
- Don't build auth UI. No login, signup, or password-reset pages. Your app's only job is to redirect unauthenticated visitors to Campus One (the previous step) and read the returned identity.
- An existing Campus One session means automatic login. Campus One keeps a session for the signed-in student; when your app redirects to the authorize endpoint, Campus One sees that session and sends the student straight back with an authorization code — no credential prompt. (Apps served on a
*.campusone.com.ngsubdomain even share the session cookie directly.) - Skip the consent screen for trusted apps. First-party/internal apps can be marked Trusted app in the developer dashboard so returning students aren't shown the scope-consent dialog at all. Otherwise, consent is shown once and then remembered until your scopes change.
- Want zero redirect flash? Use
prompt=none. Addprompt=noneto the authorize request to attempt a fully silent sign-in. If the student has a Campus One session you get a code back invisibly; if not, Campus One returnserror=login_required— catch that and fall back to a normal redirect. See Automatic & silent sign-in.
The result: a student who is logged into Campus One lands in your app already authenticated, every time.
Signing out
Logout is ecosystem-wide: redirecting a user to the end-session endpoint clears their entire Campus One session. Since your app has no login screen of its own, enable a Sign-out redirect in your app settings (Sign-In → Sign-out redirect → Return to Campus One directory), then point your "Log out" action at the end-session endpoint — Campus One handles the rest:
window.location.href =
"https://auth.campusone.com.ng/api/auth/oauth2/endsession" +
`?id_token_hint=${idToken}&client_id=${CAMPUS_ONE_CLIENT_ID}`;No post_logout_redirect_uri needed. Full details (including the custom-URL option) are in Single logout.
Testing your integration
You can fully exercise the integration locally before you have a production campusone.com.ng subdomain.
- Pending apps are live. Authorization, the consent screen, and token issuance all work while your app is in
Pendingstatus — no approval needed. - Register a separate staging app. Keep one app for local/staging (with
localhostand preview redirect URLs) and a second for production. That gives you independent test keys you can rotate freely. See Multi-app strategy. - Localhost just works. Over
http://localhost, the auth server relaxes secure-cookie and cross-subdomain rules automatically, so sessions hold without browser cookie warnings. Register the exact callback your framework uses, e.g.http://localhost:3000/api/auth/callback/campus-one. - Use test users. Sign in with any seeded student, staff, developer, or admin account on the staging deployment to verify role-based behaviour. (Ask your Campus One admin for test credentials — they aren't published here.)
- Verify the token. Always validate the ID token signature against the JWKS and check
iss,aud, andexp.
Next steps
OpenID Connect
The full OIDC reference: endpoints, scopes, token exchange, refresh
Permissions
What each scope returns and how flags gate them
Notifications
Push in-app notifications to your users
Webhooks
React to sign-in, role changes, and account events
Troubleshooting
Fixes for the most common integration errors
AI Integration
Let an AI agent do the integration for you