Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added function to check revoke (breaking changes) #16

Merged
merged 4 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,24 @@ Auth is created as a singleton object. This is because the Module Worker syntax

See official document for project ID: https://firebase.google.com/docs/projects/learn-more#project-identifiers

### `authObj.verifyIdToken(idToken: string, env?: EmulatorEnv): Promise<FirebaseIdToken>`
### `authObj.verifyIdToken(idToken: string, checkRevoked?: boolean, env?: EmulatorEnv): Promise<FirebaseIdToken>`

Verifies a Firebase ID token (JWT). If the token is valid, the promise is fulfilled with the token's decoded claims; otherwise, the promise is rejected.

See the [ID Token section of the OpenID Connect spec](http://openid.net/specs/openid-connect-core-1_0.html#IDToken) for more information about the specific properties below.

- `idToken` The ID token to verify.
- `checkRevoked` - Whether to check if the session cookie was revoked. This requires an extra request to the Firebase Auth backend to check the `tokensValidAfterTime` time for the corresponding user. When not specified, this additional check is not performed.
- `env` is an optional parameter. but this is using to detect should use emulator or not.

### `authObj.verifySessionCookie(sessionCookie: string, env?: EmulatorEnv): Promise<FirebaseIdToken>`
### `authObj.verifySessionCookie(sessionCookie: string, checkRevoked?: boolean, env?: EmulatorEnv): Promise<FirebaseIdToken>`

Verifies a Firebase session cookie. Returns a Promise with the cookie claims. Rejects the promise if the cookie could not be verified.

See [Verify Session Cookies](https://firebase.google.com/docs/auth/admin/manage-cookies#verify_session_cookie_and_check_permissions) for code samples and detailed documentation.

- `sessionCookie` The session cookie to verify.
- `checkRevoked` - Whether to check if the session cookie was revoked. This requires an extra request to the Firebase Auth backend to check the `tokensValidAfterTime` time for the corresponding user. When not specified, this additional check is not performed.
- `env` is an optional parameter. but this is using to detect should use emulator or not.

### `authObj.createSessionCookie(idToken: string, sessionCookieOptions: SessionCookieOptions, env?: EmulatorEnv): Promise<string>`
Expand All @@ -148,6 +150,28 @@ Creates a new Firebase session cookie with the specified options. The created JW

**Required** service acccount credential to use this API. You need to set the credentials with `Auth.getOrInitialize`.

### `authObj.getUser(uid: string, env?: EmulatorEnv): Promise<UserRecord>`

Gets the user data for the user corresponding to a given `uid`.

- `uid` corresponding to the user whose data to fetch.
- `env` is an optional parameter. but this is using to detect should use emulator or not.

### `authObj.revokeRefreshTokens(uid: string, env?: EmulatorEnv): Promise<void>`

Revokes all refresh tokens for an existing user.

- `uid` corresponding to the user whose refresh tokens are to be revoked.
- `env` is an optional parameter. but this is using to detect should use emulator or not.

### `authObj.setCustomUserClaims(uid: string, customUserClaims: object | null, env?: EmulatorEnv): Promise<void>`

Sets additional developer claims on an existing user identified by the provided `uid`, typically used to define user roles and levels of access. These claims should propagate to all devices where the user is already signed in (after token expiration or when token refresh is forced) and the next time the user signs in. If a reserved OIDC claim name is used (sub, iat, iss, etc), an error is thrown. They are set on the authenticated user's ID token JWT.

- `uid` - The `uid` of the user to edit.
- `customUserClaims` The developer claims to set. If null is passed, existing custom claims are deleted. Passing a custom claims payload larger than 1000 bytes will throw an error. Custom claims are added to the user's ID token which is transmitted on every authenticated request. For profile non-access related user attributes, use database or other separate storage systems.
- `env` is an optional parameter. but this is using to detect should use emulator or not.

### `WorkersKVStoreSingle.getOrInitialize(cacheKey: string, cfKVNamespace: KVNamespace): WorkersKVStoreSingle`

WorkersKVStoreSingle is created as a singleton object. This is because the Module Worker syntax only use environment variables at the time of request.
Expand Down Expand Up @@ -236,4 +260,4 @@ Access to `/admin/login` after started up Emulator and created an account (email

### Required service account key.

- [ ] Check authorized user is deleted (revoked)
- [x] Check authorized user is deleted (revoked)
20 changes: 10 additions & 10 deletions example/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Hono } from 'hono';
import { getCookie, setCookie } from 'hono/cookie';
import { csrf } from 'hono/csrf';
import { html } from 'hono/html';
import { Auth, EmulatorCredential, emulatorHost, WorkersKVStoreSingle } from '../src';
import { Auth, ServiceAccountCredential, emulatorHost, WorkersKVStoreSingle, AdminAuthApiClient } from '../src';

type Env = {
EMAIL_ADDRESS: string;
Expand All @@ -12,6 +12,9 @@ type Env = {
PUBLIC_JWK_CACHE_KEY: string;

FIREBASE_AUTH_EMULATOR_HOST: string; // satisfied EmulatorEnv
// Set JSON as string.
// See: https://cloud.google.com/iam/docs/keys-create-delete
SERVICE_ACCOUNT_JSON: string;
};

const app = new Hono<{ Bindings: Env }>();
Expand Down Expand Up @@ -46,7 +49,7 @@ app.post('/verify-header', async c => {
c.env.PROJECT_ID,
WorkersKVStoreSingle.getOrInitialize(c.env.PUBLIC_JWK_CACHE_KEY, c.env.PUBLIC_JWK_CACHE_KV)
);
const firebaseToken = await auth.verifyIdToken(jwt, c.env);
const firebaseToken = await auth.verifyIdToken(jwt, false, c.env);

return new Response(JSON.stringify(firebaseToken), {
headers: {
Expand Down Expand Up @@ -153,16 +156,13 @@ app.post('/admin/login_session', async c => {
// The session cookie will have the same claims as the ID token.
// To only allow session cookie setting on recent sign-in, auth_time in ID token
// can be checked to ensure user was recently signed in before creating a session cookie.
const auth = Auth.getOrInitialize(
const auth = AdminAuthApiClient.getOrInitialize(
c.env.PROJECT_ID,
WorkersKVStoreSingle.getOrInitialize(c.env.PUBLIC_JWK_CACHE_KEY, c.env.PUBLIC_JWK_CACHE_KV),
new EmulatorCredential() // You MUST use ServiceAccountCredential in real world
new ServiceAccountCredential(c.env.SERVICE_ACCOUNT_JSON)
);
const sessionCookie = await auth.createSessionCookie(
idToken,
{
expiresIn,
},
expiresIn,
c.env // This valus must be removed in real world
);
setCookie(c, 'session', sessionCookie, {
Expand All @@ -178,13 +178,13 @@ app.get('/admin/profile', async c => {

const auth = Auth.getOrInitialize(
c.env.PROJECT_ID,
WorkersKVStoreSingle.getOrInitialize(c.env.PUBLIC_JWK_CACHE_KEY, c.env.PUBLIC_JWK_CACHE_KV),
new EmulatorCredential() // You MUST use ServiceAccountCredential in real world
WorkersKVStoreSingle.getOrInitialize(c.env.PUBLIC_JWK_CACHE_KEY, c.env.PUBLIC_JWK_CACHE_KV)
);

try {
const decodedToken = await auth.verifySessionCookie(
session,
false,
c.env // This valus must be removed in real world
);
return c.json(decodedToken);
Expand Down
3 changes: 3 additions & 0 deletions example/wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ tsconfig = "./tsconfig.json"
# FIREBASE_AUTH_EMULATOR_HOST = ""
FIREBASE_AUTH_EMULATOR_HOST = "127.0.0.1:9099"

# See: https://cloud.google.com/iam/docs/keys-create-delete
SERVICE_ACCOUNT_JSON = "{\"type\":\"service_account\",\"project_id\":\"project12345\",\"private_key_id\":\"xxxxxxxxxxxxxxxxx\",\"private_key\":\"-----BEGIN PRIVATE KEY-----XXXXXX-----END PRIVATE KEY-----\n\",\"client_email\":\"[email protected]\",\"client_id\":\"xxxxxx\",\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\"token_uri\":\"https://oauth2.googleapis.com/token\",\"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\",\"client_x509_cert_url\":\"https://www.googleapis.com/robot/v1/metadata/x509/[email protected]\"}"

# Setup user account in Emulator UI
EMAIL_ADDRESS = "[email protected]"
PASSWORD = "test1234"
Expand Down
Loading
Loading