Google API OAuth2 : “invalid_grant” error when requesting token for Service Account with Perl

后端 未结 4 885
后悔当初
后悔当初 2021-01-06 17:52

Got the credentials for Service Account from Developer Console

First, I converted p12 private key to PEM:

openssl pkcs12 -in 

        
相关标签:
4条回答
  • 2021-01-06 18:07

    I don't know why, but the problem was with curl.

    I replaced it by WWW::Mechanize:

    my $mech = WWW::Mechanize->new( autocheck => 1 );
    $mech->post('https://accounts.google.com/o/oauth2/token',
        'Content-Type' => 'application/x-www-form-urlencoded',
        'Content' => [
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $token_request,
        ],
    );
    

    and it works.

    0 讨论(0)
  • 2021-01-06 18:17

    Just in case anybody comes here looking for an approach to obtaining a bearer token from Google Service Account Credentials in the currently provided JSON file; here's a snippet that worked for me after I couldn't use Crypt::JWT or Mojo::JWT::Google.

    use LWP::UserAgent;
    use JSON;
    use  Mojo::JWT;
    use Mojo::File;
    
    my $jwt = create_jwt_from_path_and_scopes( 'path/to/credentials.json', 'email https://www.googleapis.com/auth/compute' );
    my $ua  = LWP::UserAgent->new();
    
    my $response = $ua->post('https://www.googleapis.com/oauth2/v4/token', 
                    {   'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 
                        'assertion'  =>  $jwt 
                    }
                ); 
    
    #######################################################################
    sub create_jwt_from_path_and_scopes
    {
      my ( $path, $scope ) = @_;
      croak("No path provided")        if not defined $path;
      croak("$path no available")      if not -f $path;
      my $json = decode_json( Mojo::File->new($path)->slurp );
      croak("No Private key in $path") if not defined $json->{private_key};
      croak("Not a service account")   if $json->{type} ne 'service_account';
      my $jwt = Mojo::JWT->new();
      $jwt->algorithm('RS256');
      $jwt->secret($json->{private_key});
    
      $jwt->claims( {
          iss   => $json->{client_email},
          scope => $scope,
          aud   => 'https://www.googleapis.com/oauth2/v4/token',   
          iat   => time(),
          exp   => time()+3600   
      } );
      $jwt->set_iat( 1 );
      return $jwt->encode;
    }
    #######################################################################
    
    0 讨论(0)
  • 2021-01-06 18:20

    Change your curl command to be:

    curl -H "Content-Type: application/x-www-form-urlencoded" \
         -d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
         -d assertion=$token_request \
          https://accounts.google.com/oauth2/token
    
    0 讨论(0)
  • 2021-01-06 18:23

    Try to use BASE64URL instead of BASE64. JWT/JWS/JWE specifications use BASE64URL.

    MIME::Base64 ---> MIME::Base64::URLSafe
    encode_base64 ---> urlsafe_b64encode
    
    0 讨论(0)
提交回复
热议问题