Overview
Campus uses PocketBase’s built-in authentication system with JWT tokens stored in HTTP-only cookies for security. Authentication is required for all API endpoints.
Authentication Flow
- User authenticates via PocketBase auth endpoints
- Server stores auth token in HTTP-only cookie
- Client includes cookie in all subsequent requests
- Server validates token on each request via
locals.pb.authStore
Login
Authenticate a user with email and password.
Request
curl -X POST "https://your-domain.com/api/collections/users/auth-with-password" \
-H "Content-Type: application/json" \
-d '{
"identity": "[email protected]",
"password": "password123"
}'
Response
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"record": {
"id": "RECORD_ID",
"collectionId": "_pb_users_auth_",
"collectionName": "users",
"username": "username",
"email": "[email protected]",
"emailVisibility": false,
"verified": true,
"created": "2026-01-01 00:00:00.000Z",
"updated": "2026-01-01 00:00:00.000Z"
}
}
Email verification status
Register
Create a new user account.
Request
curl -X POST "https://your-domain.com/api/collections/users/records" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "password123",
"passwordConfirm": "password123",
"username": "newuser"
}'
User password (minimum 8 characters)
Password confirmation (must match password)
Username (optional, auto-generated if not provided)
Response
{
"id": "RECORD_ID",
"collectionId": "_pb_users_auth_",
"collectionName": "users",
"username": "newuser",
"email": "[email protected]",
"emailVisibility": false,
"verified": false,
"created": "2026-01-01 00:00:00.000Z",
"updated": "2026-01-01 00:00:00.000Z"
}
Refresh Token
Refresh an authentication token before it expires.
Request
curl -X POST "https://your-domain.com/api/collections/users/auth-refresh" \
-H "Authorization: Bearer YOUR_AUTH_TOKEN"
Response
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"record": {
"id": "RECORD_ID",
"collectionId": "_pb_users_auth_",
"collectionName": "users",
"username": "username",
"email": "[email protected]",
"created": "2026-01-01 00:00:00.000Z",
"updated": "2026-01-01 00:00:00.000Z"
}
}
Logout
Invalidate the current authentication token.
Request
curl -X POST "https://your-domain.com/api/collections/users/auth-logout" \
-H "Authorization: Bearer YOUR_AUTH_TOKEN"
Response
Request Email Verification
Send a verification email to the user.
Request
curl -X POST "https://your-domain.com/api/collections/users/request-verification" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]"
}'
Confirm Email Verification
Confirm email verification with token from email.
Request
curl -X POST "https://your-domain.com/api/collections/users/confirm-verification" \
-H "Content-Type: application/json" \
-d '{
"token": "VERIFICATION_TOKEN"
}'
Verification token from email
Request Password Reset
Send a password reset email.
Request
curl -X POST "https://your-domain.com/api/collections/users/request-password-reset" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]"
}'
Email address for password reset
Confirm Password Reset
Reset password with token from email.
Request
curl -X POST "https://your-domain.com/api/collections/users/confirm-password-reset" \
-H "Content-Type: application/json" \
-d '{
"token": "RESET_TOKEN",
"password": "newpassword123",
"passwordConfirm": "newpassword123"
}'
Client-Side Integration
On the client side, Campus hydrates the authentication state from server data:
import { hydrateClientAuth } from '$lib/pocketbase'
// In your layout or app initialization
hydrateClientAuth(token, userModel)
The authentication token is stored in an HTTP-only cookie named pb_auth to prevent XSS attacks.
Checking Authentication Status
On the server, check authentication via locals.pb.authStore:
if (!locals.pb.authStore.isValid) {
return error(401, 'Authentication required')
}
const userId = locals.pb.authStore.model?.id