next-cas-client

Maintained by the University of Hawaiʻi.
Designed for Next.js, next-cas-client
serves as an API platform to interact with a CAS server to authenticate, validate tickets, and provide session management (powered by iron-session).
Currently supports CAS 2.0, CAS 3.0 and SAML 1.1 service validation methods.
Contributions to this repo to support more validation protocols is highly encouraged! (See contributing)
Table of Contents
Getting Started
1. Installation
npm i next-cas-client
pnpm add next-cas-client
yarn add next-cas-client
2. Set Environment Variables
.env
:
NEXT_PUBLIC_BASE_URL=https://example.com
NEXT_PUBLIC_CAS_URL=https://cas.example.com/cas
NEXT_CAS_CLIENT_SAML_TOLERANCE=18000
NEXT_PUBLIC_BASE_URL
(Required): The URL to redirect to after logging-in/outNEXT_PUBLIC_CAS_URL
(Required): The URL prefix of your CAS serverNEXT_CAS_CLIENT_SAML_TOLERANCE
(Optional): The tolerance in milliseconds for drifting clocks when validating SAML tickets. Only applies to SAML 1.1 validation. Defaults to 1000 milliseconds.
.env.local
:
NEXT_CAS_CLIENT_SECRET=GenerateA32CharacterLongPassword
NEXT_CAS_CLIENT_SECRET
(Required): The secret used to encrypt/decrypt the session stored as a cookie. It must be greater than 32 characters long. Use https://1password.com/password-generator to generate a password.
3. Add API Route
App Router: app/api/cas/[client]/route.ts
:
import { ValidatorProtocol } from 'next-cas-client';
import { handleAuth } from 'next-cas-client/app';
export const GET = handleAuth({ validator: ValidatorProtocol.CAS30 });
Page Router: pages/api/cas/[client].ts
:
import { ValidatorProtocol } from 'next-cas-client';
import { handleAuth } from 'next-cas-client/pages';
export default handleAuth({ validator: ValidatorProtocol.CAS30 });
handleAuth() Options:
Usage
login(): void
(Client-Side Only)
Visits the CAS login page.
'use client';
import { login } from 'next-cas-client';
<button onClick={() => login()}>Login</button>;
login() Options:
renew
(Optional): Boolean, true
to disallow SSO. Defaults to false
.
logout(): void
(Client-Side Only)
Visits the CAS logout page.
'use client';
import { login } from 'next-cas-client';
<button onClick={() => logout()}>Logout</button>;
logout() Options:
enableSLO
(Optional): Boolean, true
to enable SLO (Single Logout). Destroys current SSO session. Defaults to false
.
getCurrentUser<T>(): Promise<T = CasUser | null>
(Server-Side Only)
Gets the current user. Returns null
if no user is logged-in.
App Router:
import { getCurrentUser } from 'next-cas-client/app';
const currentUser = await getCurrentUser();
Page Router:
import { getCurrentUser } from 'next-cas-client/pages';
export const getServerSideProps = (async (context) => {
return { props: { currentUser: await getCurrentUser(context) } };
}) satisfies GetServerSideProps<{ currentUser: CasUser | null }>;
Returns an object of type CasUser
by default. Define the generic type of getCurrentUser()
if you used the loadUser
option in handleAuth()
. The type should match the return of the loadUser
function you defined.
isLoggedIn(): Promise<boolean>
(Server-Side Only)
Returns true
if a user is logged-in.
App Router:
import { getCurrentUser } from 'next-cas-client/app';
const isLoggedIn = await isLoggedIn();
Page Router:
import { getCurrentUser } from 'next-cas-client/pages';
export const getServerSideProps = (async (context) => {
return { props: { isLoggedIn: await isLoggedIn(context) } };
}) satisfies GetServerSideProps<{ isLoggedIn: boolean }>;
Examples
A fully functional demo is available using Docker.
To start:
- Clone or download this repo
- Change directory to
/examples
- Execute
docker compose up
. A CAS server for demo purposes will launch at https://localhost:8443/cas - Change directory to
/app-router
or /pages-router
depending on the router you would like to view the example for - Execute
npm run dev
. The Next.js example app will be available at http://localhost:3000
Note: You may encounter a NET:ERR_CERT_INVALID
error in your browser when attempting to visit the CAS login page. Bypass the error by trusting the page. The browser is attempting to protect you from visiting a suspicious secure site at https://localhost.
Contributing
Please open a new issue before creating a PR. This project is currently focusing on supporting more ticket validation protocols. Any other issues and PRs created out of this scope may be rejected.
For more information on how to contribute, view here.
FAQ
Is there support for other React frameworks like Vite and Remix?
No, not at this moment.
How do I use getCurrentUser()
and isLoggedIn()
in a client component?
It is recommended to use those functions inside a server component then pass them as props into a client component.
How do I resolve the error when importing getCurrentUser()
and isLoggedIn()
from 'next-cas-client/app'
or 'next-cas-client/pages'
?
In your project's tsconfig.json
, set compilerOptions.moduleResolution
to "bundler".