Retrieving Auth0 Management APIv2 Token - auth0

As outlined in the Auth0 documentation, I am attempting to retrieve a management api token by making a POST request using jQuery from my Ember App:
getToken() {
let settings = {
"async": true,
"crossDomain": true,
"url": "https://brittshroyer.auth0.com/oauth/token",
"method": "POST",
"headers": {
"content-type": "application/json"
},
"processData": false,
"data": "{grant_type:client_credentials,
client_id: 123,
client_secret: fakesecret123,
audience: https://brittshroyer.auth0.com/api/v2/}"
}
$.ajax(settings).done(function (response) {
return console.log('RESPONSE', response);
});
}
As instructed, I have created and initialized a 'Non-Interactive Client' and I have whitelisted 'localhost:4200' (since that is where I am running my Ember App) in the Allowed Origins (CORS) section in the configuration of my client within Auth0. Still, I am running into the following CORS error upon making the POST request:
I'm fairly familiar with CORS, but clearly not familiar enough. Do I need to add a certain header to the payload? Is there a configuration step within Auth0 I am missing? Any help would be awesome.

This code works for me - please just replace with your TENANT, client_id value, and client_secret value.
<html>
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
</head>
<body>
<script>
var settings = {
async: true,
crossDomain: true,
url: "https://{{TENANT}}.auth0.com/oauth/token",
method: "POST",
headers: {
"content-type":"application/json"
},
"data": "{\"client_id\":\"Z7HtXBOBPXXXXXXXQcJ3Ma\",\"client_secret\":\"FPWb45XXXXXX96U5XmBUZkUXXXXODDJ88NY\",\"audience\":\"https://brittshroyer.auth0.com/oauth/token\",\"grant_type\":\"client_credentials\"}"
}
$.ajax(settings).done(function (response) {
console.log(response);
});
</script>
</body>
</html>
In your Client (not API) on the Auth0 Dashboard, remember to add the Allowed Callback URLs (which I believe you are already doing). eg.
Where I think your code went wrong, was somehow it was malformed JSON. In the data section of the JSON snippet above, notice how the value is escaped. This is similar to the code snippet Auth0 offer when click the Try button in the APIs section of the Dashboard.
Note on quick testing: I had npm module serve installed, so just named my snippet above temp.html and ran serve from the same folder. It is then served at http://localhost:5000/temp.html. You can see the output by refreshing the page and viewing the console in web browser developer tools.
Let me know if you have any problems, and please mark this answer as correct if it helps you solve your problem! :)

Related

Playwright: unable to login via API setting cookie (able to do it with Cypress)

I'm trying to implemented login via API following Playwright's guidelines but somehow nothing seems to be working.
As a comparison I've built the same in Cypress and it works out of the box:
Context:
Playwright Version: 1.30
Operating System: Mac
Node.js version: v16.19.0
Browser: Chromium
I am unable to make a simple API login that works perfectly using Cypress instead. Let me share the 2 code snippets for comparison:
Simple test case:
API request to the login end-point - Auth token is retrieved
set the auth token as a cookie
navigate to a page that is accessible only if authenticated
Code Snippet
Cypress (working fine)
const body = {
username: 'username...',
password: 'password',
rememberMe: true,
};
describe('Login via API to management console', () => {
it('Login via API to management console', () => {
cy.request({
method: 'POST',
url: loginEndPoint,
headers: {
'Content-Type': 'application/json',
},
body,
}).then((response) => {
cy.setCookie('Authorization', `Token ${response.body.data.token}`);
});
cy.visit(`/management`);
});
});
Playwright (not working)
test('Login via API', async ({ browser }) => {
const context = await browser.newContext();
const page = await context.newPage();
const loginResponse = await context.request.post(`https://${process.env.MANAGEMENT_URL}/web/api/v2.1/users/login`, {
data: {
username: process.env.MANAGEMENT_USER,
password: process.env.MANAGEMENT_PASSWORD,
rememberMe: true,
}
});
const {
data: { token },
} = await loginResponse.body().then((b) => {
return JSON.parse(b.toString());
});
expect(token).toMatch(/^[a-z0-9]{80}$/)
await context.addCookies([{ name: 'Authorization', value: `Token ${token}`, path: '/', domain: `https://${process.env.MANAGEMENT_URL}` }]);
await page.goto(`https://${process.env.MANAGEMENT_URL}/management/`);
await expect(page).toHaveURL(/management/);
});
Describe the bug
Both scripts are successful at retrieving the authentication token but somehow either I'm doing something wrong with setting the cookie in Playwright or there is an issue. I'd assume the 2 scripts should be comparable.
Furthermore: I've tried to execute login via UI using global-setup, saving the storage-state, loading it before running the test and it fails also in this case... so there is something that is not setting properly the state in this case or the cookie in the previous one.
Not entirely sure why the cookie approach wasn’t working, perhaps the https:// part should be removed from the domain?
That being said, in Playwright you shouldn’t even need to do that especially within a single test, looking at the Playwright docs on signing in via the API and related page about the request context particularly under cookie management. The associated request and browser contexts share cookies, so once you complete the login request, the browser should already have the cookie state too and be logged in, so you should be able to just remove getting the token and adding the cookie. Or you can login with the API in the global setup even, as that doc showed. Just make sure in that case to save the storage state, and specify the same file in your config.
I see you tried the global setup approach (through the UI, but you can use the API since you have it), not sure what happened there. I would say to ensure that you specified the storageState in the config; I would be curious how you loaded it as mentioned, and if you’re still having problems maybe share the code you’re using for that piece?
Hope that helps or we can troubleshoot further!

Feedly API with NuxtJS Axios

I am trying to access the Feedly API via my nuxtjs site. To do so, I am using the nuxt-axios module.
To get started, I take note of the Feedly API instructions:
We offer a standard OAuth 2.0 authentication module which provide the application an OAuth access token. Most endpoints expect an Authorization header.
$ curl -H 'Authorization: OAuth [your developer access token]' https://cloud.feedly.com/v3/profile
I now attempt to integrate this into nuxtjs-axios.
First, I set up my nuxt-config.js file:
export default {
...
plugins: [{ src: `~/plugins/axios.js` }],
modules: [
'#nuxtjs/axios',
],
axios: {
credentials: true
},
env: {
FEEDLY_ACCESS_TOKEN:
[MY_FEEDLY_DEV_ACCESS_TOKEN]
},
...
}
I then create a axios.js plugin in the plugins folder (which is imported into the nuxt-config.js file that I noted above):
export default function({ $axios }) {
$axios.setHeader('Authorization', `OAuth ${process.env.FEEDLY_ACCESS_TOKEN}`)
}
The problem is that I have no idea what I'm supposed to put in the axios.js plugin file --- or even if that is the right way to do this. What I did is really just a stab in the dark.
So my question is, how can I implement the Feedly API into nuxtjs using the nuxtjs-axios module?
Thanks.
Use interceptor:
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
});
https://github.com/axios/axios/blob/master/README.md#interceptors
What I've understood of the nuxt-axios documentation is that the plugin.axios file is used for adding "default" behavior (axios helpers: https://axios.nuxtjs.org/helpers/)
I think that you've got the plugin right (if the token is the only thing you need to add to your header).
With the nuxt-axios enabled you can now use the this.$axios.get/post.
Have you tried to run a component with:
this.$axios.get('**feedly_url_api_url_here**').then(response)....

Using Cypress to Test an App That Relies on OAuth

I've inherited a Node.js web app that uses relies on OAuth. Whenever you visit a page the app ensures you've authenticated. Please note, there no Angular, React, Vue, etc here. Each page is straight up HTML.
I want to test this site using Cypress. My problem is, I'm stuck on the initial redirect from the auth provider. Cypress acknowledge OAuth is a challenge.
commands.js
Cypress.Commands.add('login', (credentials) => {
var settings = {
'clientId':'<id>',
'scope':'<scope-list>',
...
};
var body = `client_id=${settings.clientId}&scope=${settings.scope}...`;
var requestOptions = {
method: 'POST',
url: 'https://login.microsoftonline.com/...',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: body
}
cy.request(requestOptions);
});
Then, in my test, I have:
context('Home', () => {
it('Visits Successfully', () => {
cy.login();
cy.title().should('include', 'welcome');
});
});
In the test runner, I see the login POST request is occurring. I confirmed that an access token is being received using a console.log, however, my title is empty. It's like the redirect after OAuth isn't happening in Cypress. However, when I visit the site in the browser, the redirect is happening as expected.
What am I missing?
What you might be missing is confusing between the actual UI flow and the programmatic flow of doing OAuth with a 3rd party website.
What you would want to do is to complete the programmatic login and then send the required parameters to your OAuth callback URL for your app manually in the test code.
an example is given here (though it uses a different grant type it gives you an idea) https://auth0.com/blog/end-to-end-testing-with-cypress-and-auth0/#Writing-tests-using-Cypress-Login-Command
another issue on the cypress github that deals with a similar problem
https://github.com/cypress-io/cypress/issues/2085
this also might help:
https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/logging-in__single-sign-on/cypress/integration/logging-in-single-sign-on-spec.js

Podio POST request returns unauthorized

I'm working on a Podio integration as a Slack bot.
I'm starting to use it just for use for my company to test it, then I could share it with everybody.
I've used the podio-js platform with Node JS, and started locally with a "web app" by starting from this example: https://github.com/podio/podio-js/tree/master/examples/password_auth
I need to do a post request, so I maintained all the code of the example in order to log in with user and password. The original code worked, then I changed the code to make a post request, in particular I change the lines of index.js into this:
router.get('/user', function(req, res) {
podio.isAuthenticated().then(function () {
var requestData = { "title": "sample_value" };
return podio.request('POST', '/item/app/15490175', requestData);
})
.then(function(responseData) {
res.render('user', { data: responseData });
})
.catch(function () {
res.send(401);
});
});
But in the end is giving a "Unauthorized" response.
It seems like the password auth doesn't let to make POST request to add new items! Is that possible?
I've already read all the documentation but I'm not able to explain why and how I can solve this.
Regards

google places api error with jquery ajax call... html_attributions

I'm using the new google places api with jquery/ajax. When I run this code:
$.ajax({
url: "https://maps.googleapis.com/maps/api/place/search/json?location=40.7834345,-73.9662495&radius=50&sensor=false&key=Your_API_KEY_HERE",
dataType: "jsonp",
data: {
name: 'rogue'
},
success: function( data ) {
console.log(data)
}
});
I get this error: invalid label html_attributions []; I think this is preventing me from seeing the output object in the console, although I can see the response coming back fine in the json tab in firebug
It seems like the places api does not support ajax so far.
It not enough that the server responds with proper JSON. The answering server has to support JSONP and surround the JSON answer with a callback generated by jQuery. The response must look like that:
jQuery17101705844928510487_1324249734338({"data":"whatever"});
The hack that JSONP does, is to interpret the response as script, because the script-Tag is not affected by the Same-Origin-Policy. Without the callback you have no chance to do that in the browser.
If its not supported you have to do the requests from your server..
Server-Example with PHP:
<?php
header("Content-Type:text/javascript"); // avoid browser warnings
$request = new HttpRequest("http://programmingisart.com/json-data-source.php", HttpRequest::METH_GET);
$request->send();
$json_data = $request->getResponseBody();
// wrap the data as with the callback
$callback = isset($_GET["callback"]) ? $_GET["callback"] : "alert";
echo $callback."(".$json_data.");";
Client-Example with jQuery:
<div id="json-result"></div>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
dataType: "jsonp",
url: "jsonp-wrapper.php",
success: function(data) {
$("#json-result").html(JSON.stringify(data));
},
error: function() {
alert("error");
}
});
});
</script>
You can replace the PHP-code with any other server-platform and do the required steps.
HTTP-Request to a JSON source
Wrap the JSON as with a callback-function