Last active
May 27, 2021 13:17
-
-
Save schirrmacher/ab597e62953eef9f635c576d389fe4e2 to your computer and use it in GitHub Desktop.
Backend Implementation of Apple's DeviceCheck and Google's SafetyNet Attestation API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import BaseService from "./BaseService"; | |
import BaseCoordinator from "./BaseCoordinator"; | |
import { DeviceCheckParams, DeviceCheckService } from "./DeviceCheckService"; | |
import { GoogleSafetyNetAttestationService } from "./GoogleSafetyNetAttestationService"; | |
import { AppleDeviceCheckService } from "./AppleDeviceCheckService"; | |
import * as UserAgentParser from "../helper/UserAgentParser"; | |
export default class DeviceCheckCoordinator extends BaseCoordinator { | |
private loggingTag = "DeviceAuthenticityCheck"; | |
public async shouldProceed(userAgent: string, token: string | undefined, timestamp: number, binding: string): Promise<boolean> { | |
if (!token) { | |
this.logger.warn(`${this.loggingTag}: ${userAgent}: no token given`); | |
return false; | |
} | |
let deviceCheckService: BaseService & DeviceCheckService | undefined; | |
const deviceCheckParams: DeviceCheckParams = { | |
timestamp, | |
token, | |
binding, | |
}; | |
if (UserAgentParser.os(userAgent) === "iOS") { | |
deviceCheckService = new AppleDeviceCheckService(); | |
} else if (UserAgentParser.os(userAgent) === "Android") { | |
deviceCheckService = new GoogleSafetyNetAttestationService(); | |
} else { | |
this.logger.warn(`${this.loggingTag}: ${userAgent}: invalid user agent`); | |
// cannot be the case for valid clients => do not proceed | |
return false; | |
} | |
if (deviceCheckService && deviceCheckParams) { | |
try { | |
const isDeviceAllowedToProceed = await deviceCheckService.shouldProceed(deviceCheckParams); | |
if (isDeviceAllowedToProceed) { | |
this.logger.info(`${this.loggingTag}: ${userAgent}: device authenticated`); | |
return true; | |
} else { | |
this.logger.warn(`${this.loggingTag}: ${userAgent}: suspicious behavior detected`); | |
return false; | |
} | |
} catch (error) { | |
this.logger.error(`${this.loggingTag}: ${userAgent}: device check skipped due to error: ${error}`); | |
// external errors force us to skip check => proceed | |
// otherwise Apple/Google failures can block our services | |
return true; | |
} | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Where is
AppleDeviceCheckService
? :)