title: NetSuite SuiteTalk Token Authentication : Invalid login attempt
body: <p>I am using the Netsuite web services (SuiteTalk) api but keep getting a Invalid login attempt error when using a tokenPassport. As the token authentication seems quite complex I will include all the steps i have taken.</p>
  
  <p>I have retreived the account id from Setup > Integration > Web Service Preferences</p>
  
  <p>I have set up a new role with all Authentication boxes unchecked. 
  In the permissions > Setup I have added the following permissions</p>
  
  <ul>
  <li><p>Access Token Management = Full</p></li>
  <li><p>User Access Tokens =  Full</p></li>
  <li><p>Web Services = Full</p></li>
  </ul>
  
  <p>I have added the new role to my User Access Permissions</p>
  
  <p>I have created a new application in Setup > Integration > Manager Integrations
  Under the Authentication tab I have selected TOKEN-BASED Authentication</p>
  
  <p>I have created a new access token in the Setup > Users/Roles > Access Tokens with the following settings</p>
  
  <ul>
  <li><p>Application Name =  the new applicaiton </p></li>
  <li><p>User = me</p></li>
  <li><p>Role = the new role</p></li>
  <li><p>Token Name = renamed to something that makes sense</p></li>
  </ul>
  
  <p>My request xml looks like</p>
  
  <pre><code>&lt;env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:msg="urn:messages_2016_2.platform.webservices.netsuite.com" 
  xmlns:core="urn:core_2016_2.platform.webservices.netsuite.com"&gt;
    &lt;env:Header&gt;
      &lt;msg:tokenPassport&gt;
        &lt;core:account&gt;123XXXX_SB1&lt;/core:account&gt;
        &lt;core:consumerKey&gt;MY_CONSUMER_KEY&lt;/cre:consumerKey&gt;
        &lt;core:token&gt;MY_TOKEN_ID&lt;/core:token&gt;
        &lt;core:nonce&gt;ZcVszy7ySJ3Ji8PIgwlW&lt;/core:nonce&gt;
        &lt;core:timestamp&gt;1530692570&lt;/core:timestamp&gt;
        &lt;core:signature algorithm="HMAC-SHA256"&gt;nN7V4PH9qWNT9BocMQzKcFetqZ3QxpxutDJ8iZjSmH8=&lt;/core:signature&gt;
      &lt;/msg:tokenPassport&gt;
    &lt;/env:Header&gt;
    &lt;env:Body&gt;
      &lt;msg:get&gt;
        &lt;msg:baseRef xsi:type="core:RecordRef" internalId="1234567" type="customer"/&gt;
      &lt;/msg:get&gt;
    &lt;/env:Body&gt;
  &lt;/env:Envelope&gt;  
  </code></pre>
  
  <p>I am using the following ruby class to generate the nonce and signature</p>
  
  <pre><code>class NetSuiteToken
      attr_reader :account, :consumer_key, :consumer_secret, :token_id, :token_secret
  
      def initialize(account, consumer_key, consumer_secret, token_id, token_secret)
        @account = account.to_s
        @consumer_key = consumer_key
        @consumer_secret = consumer_secret
        @token_id = token_id
        @token_secret = token_secret
      end
  
      def passport
        {
          'msg:tokenPassport' =&gt; {
            'core:account' =&gt; account,
            'core:consumerKey' =&gt; consumer_key,
            'core:token' =&gt; token_id,
            'core:nonce' =&gt; nonce,
            'core:timestamp' =&gt; timestamp,
            'core:signature' =&gt; signature,
            :attributes! =&gt; { 'core:signature' =&gt; { 'algorithm' =&gt; 'HMAC-SHA256' } }
          }
        }
      end
  
      private
  
      def signature
        Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), signature_key, signature_data))
      end
  
      def signature_key
        "#{consumer_secret}&amp;#{token_secret}"
      end
  
      def signature_data
        "#{account}&amp;#{consumer_key}&amp;#{token_id}&amp;#{nonce}&amp;#{timestamp}"
      end
  
      def nonce
        @nonce ||= Array.new(20) { alphanumerics.sample }.join
      end
  
      def alphanumerics
        [*'0'..'9',*'A'..'Z',*'a'..'z']
      end
  
      def timestamp
        @timestamp ||= Time.now.to_i
      end
  end
  </code></pre>
  
  <p>If anybody could offer any assistance it would be highly appreciated.</p>