<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Question Re: Get OAuth2 access token via Javascript in Technology Q&amp;A</title>
    <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817347#M4813285</link>
    <description>&lt;P&gt;Dear all,&lt;/P&gt;&lt;P&gt;I finally find the root cause of my problem. It's purely my own mistake. Sorry for the confusion caused.&lt;/P&gt;&lt;P&gt;When I wrote the codes in the Javascript, I copied the clientid and clientsecret incorrectly. In fact, I copied the ClientID and ClientSecret of &lt;STRONG&gt;Cloud Foundry Authentication&lt;/STRONG&gt; instead of &lt;STRONG&gt;Event Mesh&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;When I created the testing project with .NET, I unconsciously used the correct id &amp;amp; secret as I reused the encrypted strings for clientid and clientsecret in a config file from another project.&lt;/P&gt;&lt;P&gt;A big thank you to Dinu, Gregor, and Martin for sharing your insightful comments. Because of your comments, I start to think it would be my own problem instead of some weird behavior from the system. &lt;STRONG&gt;Lesson learned from this experience&lt;/STRONG&gt;:&lt;/P&gt;&lt;OL&gt;
&lt;LI&gt;The length of access token from &lt;STRONG&gt;Cloud Foundry Authentication&lt;/STRONG&gt; is 1601, and for &lt;STRONG&gt;Event Mesh&lt;/STRONG&gt; it's 1869.&lt;/LI&gt;&lt;LI&gt;Back to the original purpose (to fetch the OAuth2 access token in Javascript), below are the workable code block.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Solution 1:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;// Solution 1 from Martin Stenzig
async function getEMAccessToken() {
const EMTokenURL = tokenUrl;
const EMClientID = clientId;
const EMClientSecret = clientSecret;
// specify form parameters
const formParams = new URLSearchParams();
formParams.append('grant_type', 'client_credentials');
formParams.append('client_id', EMClientID);
formParams.append('client_secret', EMClientSecret);
// Assemble the post options
const postOptions = {
method: 'POST',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
body: formParams
};
const response = await fetch(EMTokenURL, postOptions);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.access_token;
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Solution 2:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;// Alternative solution from mine
async function getEMAccessToken() {
    const EMTokenURL = 'your-token-url';
    const EMClientID = 'your-client-id';
    const EMClientSecret = 'your-client-secret';

    const credentials = Buffer.from(`${EMClientID}:${EMClientSecret}`).toString('base64');

    const response = await fetch(EMTokenURL, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': `Basic ${credentials}`
        },
        body: 'grant_type=client_credentials'
    });

    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return data.access_token;
}&amp;lt;br&amp;gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Thanks Martin for sharing the codes, I have quoted them above, it could be a good reference for others who are interested in this topic.&lt;/P&gt;&lt;P&gt;Thanks Gregor for reminding me of the CAP way of messaging handling which I will try later and post another question on it. For special use case, the current codes works fine, but I will rethink it and may consult you again if I encounter issue. &lt;/P&gt;&lt;P&gt;Thanks Dino for sharing the online tool of "JSON Web Tokens - jwt.io", it will be useful for my future exploration.&lt;/P&gt;&lt;P&gt;Last I am not sure what shall I do for this question, shall I delete this question? In fact, my initial assumption (I have encountered an weird behavior from system) is incorrect. If it still offer some value for others, I will leave it there. To consider the relevance to the topic of this question, I may accept Martin's answer as the best answer. I need some advice from the admin or regular members in this community. &lt;/P&gt;</description>
    <pubDate>Fri, 12 Jan 2024 08:44:39 GMT</pubDate>
    <dc:creator>WayneSG</dc:creator>
    <dc:date>2024-01-12T08:44:39Z</dc:date>
    <item>
      <title>Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaq-p/12817338</link>
      <description>&lt;P&gt;I am using below code to fetch the token from Event Mesh server, it succeeded with no error.&lt;/P&gt;
  &lt;P&gt;However, this token is incorrect, the length is only 1601, and the correct token length shall be 1869. &lt;/P&gt;
  &lt;P&gt;This causes the next code block of publishing an event to SAP event mesh failed with unauthorized error message.&lt;/P&gt;
  &lt;P&gt;Did anyone succeed to get a correct token before? Please help, thanks. &lt;/P&gt;
  &lt;P&gt;const fetch = require('node-fetch');&lt;/P&gt;
  &lt;PRE&gt;&lt;CODE&gt;async function getEMAccessToken() {
    const EMTokenURL = 'your-token-url';
    const EMClientID = 'your-client-id';
    const EMClientSecret = 'your-client-secret';

    const credentials = Buffer.from(`${EMClientID}:${EMClientSecret}`).toString('base64');

    const response = await fetch(EMTokenURL, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': `Basic ${credentials}`
        },
        body: 'grant_type=client_credentials'
    });

    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return data.access_token;
}&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 09 Jan 2024 10:04:22 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaq-p/12817338</guid>
      <dc:creator>WayneSG</dc:creator>
      <dc:date>2024-01-09T10:04:22Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817339#M4813277</link>
      <description>&lt;P&gt;Why do you say that the token has to be of length 1869? &lt;/P&gt;</description>
      <pubDate>Tue, 09 Jan 2024 12:14:33 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817339#M4813277</guid>
      <dc:creator>Dinu</dc:creator>
      <dc:date>2024-01-09T12:14:33Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817340#M4813278</link>
      <description>&lt;P&gt;If you're using CAP why to you want to establish the connection manually. Have you followed the documentation:&lt;/P&gt;&lt;P&gt;&lt;A href="https://cap.cloud.sap/docs/guides/messaging/#sap-event-mesh" target="test_blank"&gt;https://cap.cloud.sap/docs/guides/messaging/#sap-event-mesh&lt;/A&gt;&lt;/P&gt;&lt;P&gt;?&lt;/P&gt;</description>
      <pubDate>Tue, 09 Jan 2024 12:58:08 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817340#M4813278</guid>
      <dc:creator>gregorw</dc:creator>
      <dc:date>2024-01-09T12:58:08Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817341#M4813279</link>
      <description>&lt;P&gt;Hi Dinu,&lt;/P&gt;&lt;P&gt;Thanks for your question, While I am testing the code above, I am able to get the access token, however, in next step to publish an event to SAP Event Mesh, I always got "Unauthorized" error.&lt;/P&gt;&lt;P&gt;After almost several hours struggling, I finally decide to write .NET desktop application to verify the logic, and it works. Then I use the access token I have retrieved in .NET application and paste it to my Javascript code block for publishing event, it also works fine.&lt;/P&gt;&lt;P&gt;So I just do a comparison between the access token from Javascript code and .NET Application, then I find the length is different. Actually the first 185 characters of the access token are same. &lt;/P&gt;</description>
      <pubDate>Tue, 09 Jan 2024 13:02:16 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817341#M4813279</guid>
      <dc:creator>WayneSG</dc:creator>
      <dc:date>2024-01-09T13:02:16Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817342#M4813280</link>
      <description>&lt;P&gt;Don't know if it makes a difference, but I usually attach then credentials to the body, not the header... &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt; // specify form parameters
      const formParams = new URLSearchParams()
      formParams.append('grant_type', 'client_credentials')
      formParams.append('client_id', '[clientIdValue]')
      formParams.append('client_secret', '[client secret value]')

      // Assemble the post options
      const postOptions = {
        method: 'POST',
        headers: {
          'Content-type': 'application/x-www-form-urlencoded'
        },
        body: formParams
      }

      // console.log('Post options: ', tokenUrl, post_options);
      fetch(tokenUrl, postOptions)
        .then(res =&amp;gt; res.json())
...&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 09 Jan 2024 18:50:13 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817342#M4813280</guid>
      <dc:creator>martinstenzig</dc:creator>
      <dc:date>2024-01-09T18:50:13Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817343#M4813281</link>
      <description>&lt;P&gt;Hi Martin,&lt;/P&gt;&lt;P&gt;Thanks for your suggestion, I follow your example, below is my revised codes. However, after testing, the result is same, it will retrieve an incorrect access token string of 1601 length.&lt;/P&gt;&lt;P&gt;Note: Below codes block is for reference, it does not solve the token issue.&lt;/P&gt;&lt;P&gt;&lt;EM&gt;    async function getEMAccessToken() {&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        const EMTokenURL = tokenUrl;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        const EMClientID = clientId;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        const EMClientSecret = clientSecret;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;    &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        // specify form parameters&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        const formParams = new URLSearchParams();&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        formParams.append('grant_type', 'client_credentials');&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        formParams.append('client_id', EMClientID);&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        formParams.append('client_secret', EMClientSecret);&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;    &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        // Assemble the post options&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        const postOptions = {&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;            method: 'POST',&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;            headers: {&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;                'Content-type': 'application/x-www-form-urlencoded'&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;            },&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;            body: formParams&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        };&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;    &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        const response = await fetch(EMTokenURL, postOptions);&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;    &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        if (!response.ok) {&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;            throw new Error(`HTTP error! status: ${response.status}`);&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        }&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;    &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        const data = await response.json();&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;        return data.access_token;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;    }&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 09 Jan 2024 21:11:48 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817343#M4813281</guid>
      <dc:creator>WayneSG</dc:creator>
      <dc:date>2024-01-09T21:11:48Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817344#M4813282</link>
      <description>&lt;P&gt;Hi Gregor, thanks for your comment, the manual connection is for a special use case.&lt;/P&gt;&lt;P&gt;And I also try to follow the cap document on event mesh, but I encounter some issue on deploying the project onto Cloud Foundry, once I settle the deployment issue, I will try that again.&lt;/P&gt;</description>
      <pubDate>Tue, 09 Jan 2024 21:19:37 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817344#M4813282</guid>
      <dc:creator>WayneSG</dc:creator>
      <dc:date>2024-01-09T21:19:37Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817345#M4813283</link>
      <description>&lt;P&gt;Hi Jin,&lt;/P&gt;&lt;P&gt;please use comments when the part you're posing isn't a solution to the problem.&lt;/P&gt;&lt;P&gt;Maybe you describe us this "special use case" and we can help to find alternative solution options.&lt;/P&gt;&lt;P&gt;Best Regards&lt;BR /&gt;Gregor&lt;/P&gt;</description>
      <pubDate>Tue, 09 Jan 2024 21:24:49 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817345#M4813283</guid>
      <dc:creator>gregorw</dc:creator>
      <dc:date>2024-01-09T21:24:49Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817346#M4813284</link>
      <description>&lt;P&gt;Try decoding the tokens perhaps using &lt;A href="https://jwt.io/"&gt;JSON Web Tokens - jwt.io&lt;/A&gt; and check what is different between the payloads of the tokens. &lt;/P&gt;&lt;P&gt;Warning: Tokens are credentials. You should be aware of the risks in sharing these with external sites. &lt;/P&gt;</description>
      <pubDate>Wed, 10 Jan 2024 07:20:22 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817346#M4813284</guid>
      <dc:creator>Dinu</dc:creator>
      <dc:date>2024-01-10T07:20:22Z</dc:date>
    </item>
    <item>
      <title>Re: Get OAuth2 access token via Javascript</title>
      <link>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817347#M4813285</link>
      <description>&lt;P&gt;Dear all,&lt;/P&gt;&lt;P&gt;I finally find the root cause of my problem. It's purely my own mistake. Sorry for the confusion caused.&lt;/P&gt;&lt;P&gt;When I wrote the codes in the Javascript, I copied the clientid and clientsecret incorrectly. In fact, I copied the ClientID and ClientSecret of &lt;STRONG&gt;Cloud Foundry Authentication&lt;/STRONG&gt; instead of &lt;STRONG&gt;Event Mesh&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;When I created the testing project with .NET, I unconsciously used the correct id &amp;amp; secret as I reused the encrypted strings for clientid and clientsecret in a config file from another project.&lt;/P&gt;&lt;P&gt;A big thank you to Dinu, Gregor, and Martin for sharing your insightful comments. Because of your comments, I start to think it would be my own problem instead of some weird behavior from the system. &lt;STRONG&gt;Lesson learned from this experience&lt;/STRONG&gt;:&lt;/P&gt;&lt;OL&gt;
&lt;LI&gt;The length of access token from &lt;STRONG&gt;Cloud Foundry Authentication&lt;/STRONG&gt; is 1601, and for &lt;STRONG&gt;Event Mesh&lt;/STRONG&gt; it's 1869.&lt;/LI&gt;&lt;LI&gt;Back to the original purpose (to fetch the OAuth2 access token in Javascript), below are the workable code block.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Solution 1:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;// Solution 1 from Martin Stenzig
async function getEMAccessToken() {
const EMTokenURL = tokenUrl;
const EMClientID = clientId;
const EMClientSecret = clientSecret;
// specify form parameters
const formParams = new URLSearchParams();
formParams.append('grant_type', 'client_credentials');
formParams.append('client_id', EMClientID);
formParams.append('client_secret', EMClientSecret);
// Assemble the post options
const postOptions = {
method: 'POST',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
body: formParams
};
const response = await fetch(EMTokenURL, postOptions);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.access_token;
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Solution 2:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;// Alternative solution from mine
async function getEMAccessToken() {
    const EMTokenURL = 'your-token-url';
    const EMClientID = 'your-client-id';
    const EMClientSecret = 'your-client-secret';

    const credentials = Buffer.from(`${EMClientID}:${EMClientSecret}`).toString('base64');

    const response = await fetch(EMTokenURL, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': `Basic ${credentials}`
        },
        body: 'grant_type=client_credentials'
    });

    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return data.access_token;
}&amp;lt;br&amp;gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Thanks Martin for sharing the codes, I have quoted them above, it could be a good reference for others who are interested in this topic.&lt;/P&gt;&lt;P&gt;Thanks Gregor for reminding me of the CAP way of messaging handling which I will try later and post another question on it. For special use case, the current codes works fine, but I will rethink it and may consult you again if I encounter issue. &lt;/P&gt;&lt;P&gt;Thanks Dino for sharing the online tool of "JSON Web Tokens - jwt.io", it will be useful for my future exploration.&lt;/P&gt;&lt;P&gt;Last I am not sure what shall I do for this question, shall I delete this question? In fact, my initial assumption (I have encountered an weird behavior from system) is incorrect. If it still offer some value for others, I will leave it there. To consider the relevance to the topic of this question, I may accept Martin's answer as the best answer. I need some advice from the admin or regular members in this community. &lt;/P&gt;</description>
      <pubDate>Fri, 12 Jan 2024 08:44:39 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/get-oauth2-access-token-via-javascript/qaa-p/12817347#M4813285</guid>
      <dc:creator>WayneSG</dc:creator>
      <dc:date>2024-01-12T08:44:39Z</dc:date>
    </item>
  </channel>
</rss>

