Skip to content

Commit 831bbca

Browse files
authored
Merge pull request #21 from HiraiKyo/main
fixed iat error of 1 second earlier
2 parents fba6eee + a9f993f commit 831bbca

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

src/auth.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@ export class BaseAuth {
5454
* @param env - An optional parameter specifying the environment in which the function is running.
5555
* If the function is running in an emulator environment, this should be set to `EmulatorEnv`.
5656
* If not specified, the function will assume it is running in a production environment.
57-
*
57+
* @param clockSkewSeconds - The number of seconds to tolerate when checking the `iat`.
58+
* This is to deal with small clock differences among different servers.
5859
* @returns A promise fulfilled with the
5960
* token's decoded claims if the ID token is valid; otherwise, a rejected
6061
* promise.
6162
*/
62-
public async verifyIdToken(idToken: string, checkRevoked = false, env?: EmulatorEnv): Promise<FirebaseIdToken> {
63+
public async verifyIdToken(idToken: string, checkRevoked = false, env?: EmulatorEnv, clockSkewSeconds?: number): Promise<FirebaseIdToken> {
6364
const isEmulator = useEmulator(env);
64-
const decodedIdToken = await this.idTokenVerifier.verifyJWT(idToken, isEmulator);
65+
const decodedIdToken = await this.idTokenVerifier.verifyJWT(idToken, isEmulator, clockSkewSeconds);
6566
// Whether to check if the token was revoked.
6667
if (checkRevoked) {
6768
return await this.verifyDecodedJWTNotRevokedOrDisabled(decodedIdToken, AuthClientErrorCode.ID_TOKEN_REVOKED, env);

src/token-verifier.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -226,23 +226,31 @@ export class FirebaseTokenVerifier {
226226
*
227227
* @param jwtToken - The Firebase Auth JWT token to verify.
228228
* @param isEmulator - Whether to accept Auth Emulator tokens.
229+
* @param clockSkewSeconds - The number of seconds to tolerate when checking the token's iat. Must be between 0-60, and an integer. Defualts to 0.
229230
* @returns A promise fulfilled with the decoded claims of the Firebase Auth ID token.
230231
*/
231-
public verifyJWT(jwtToken: string, isEmulator = false): Promise<FirebaseIdToken> {
232+
public verifyJWT(jwtToken: string, isEmulator = false, clockSkewSeconds: number = 5): Promise<FirebaseIdToken> {
232233
if (!isString(jwtToken)) {
233234
throw new FirebaseAuthError(
234235
AuthClientErrorCode.INVALID_ARGUMENT,
235236
`First argument to ${this.tokenInfo.verifyApiName} must be a ${this.tokenInfo.jwtName} string.`
236237
);
237238
}
238-
return this.decodeAndVerify(jwtToken, isEmulator).then(payload => {
239+
240+
if (clockSkewSeconds < 0 || clockSkewSeconds > 60 || !Number.isInteger(clockSkewSeconds)) {
241+
throw new FirebaseAuthError(
242+
AuthClientErrorCode.INVALID_ARGUMENT,
243+
'clockSkewSeconds must be an integer between 0 and 60.'
244+
)
245+
}
246+
return this.decodeAndVerify(jwtToken, isEmulator, clockSkewSeconds).then(payload => {
239247
payload.uid = payload.sub;
240248
return payload;
241249
});
242250
}
243251

244-
private async decodeAndVerify(token: string, isEmulator: boolean): Promise<FirebaseIdToken> {
245-
const currentTimestamp = Math.floor(Date.now() / 1000);
252+
private async decodeAndVerify(token: string, isEmulator: boolean, clockSkewSeconds: number = 5): Promise<FirebaseIdToken> {
253+
const currentTimestamp = Math.floor(Date.now() / 1000) + clockSkewSeconds;
246254
try {
247255
const rs256Token = this.safeDecode(token, isEmulator, currentTimestamp);
248256
const { payload } = rs256Token.decodedToken;

0 commit comments

Comments
 (0)