Exchanges a valid authorization code for an AuthToken.
If the authorization code has not expired, has not been used, matches the client ID, and the client secret is correct, it will return a valid AuthToken. Otherwise, it will throw an appropriate AuthRequestError.
Source
Future<AuthToken> exchange( String authCodeString, String clientID, String clientSecret, {int expirationInSeconds: 3600}) async { if (clientID == null) { throw new AuthServerException(AuthRequestError.invalidClient, null); } AuthClient client = await clientForID(clientID); if (client == null) { throw new AuthServerException(AuthRequestError.invalidClient, null); } if (authCodeString == null) { throw new AuthServerException(AuthRequestError.invalidRequest, null); } if (clientSecret == null) { throw new AuthServerException(AuthRequestError.invalidClient, client); } if (client.hashedSecret != hashPassword(clientSecret, client.salt)) { throw new AuthServerException(AuthRequestError.invalidClient, client); } AuthCode authCode = await storage.fetchAuthCodeByCode(this, authCodeString); if (authCode == null) { throw new AuthServerException(AuthRequestError.invalidGrant, client); } // check if valid still if (authCode.isExpired) { await storage.revokeAuthCodeWithCode(this, authCode.code); throw new AuthServerException(AuthRequestError.invalidGrant, client); } // check that client ids match if (authCode.clientID != client.id) { throw new AuthServerException(AuthRequestError.invalidGrant, client); } // check to see if has already been used if (authCode.hasBeenExchanged) { await storage.revokeTokenIssuedFromCode(this, authCode); throw new AuthServerException(AuthRequestError.invalidGrant, client); } AuthToken token = _generateToken( authCode.resourceOwnerIdentifier, client.id, expirationInSeconds, scopes: authCode.requestedScopes); await storage.storeToken(this, token, issuedFrom: authCode); return token; }