STRAPI: Using auth0 for API Authentication in Strapi works and works not - auth0

Node: v12.16.1
Strapi: 3.0.0-beta.20.1
I'm new to strapi and have to say at first: I love it!
I want to use Strapi in addition with Angular 9 and for authentication I want to use Auth0.
For my setup with Auth0 I followed the guide in the strapi documentation and customizied my permissons.js in the user-permissions plugin.
Well!
I have a very confusing issue.
When I get back my access_token from Auth0 I put it to my calls as bearer authentication token, the request to the strapi endpoint works mostly for the first time, maybe sometimes the second and many more calls also, and then it fails. If I wait a few seconds then it works again, and after a successful call also it fails again. (also testing outside my angular-app with postman - same behavior)
If I work with the strapi jwt, it works permanantly, independet from my frequency of requests.
This is confusing me since a couple of days.
My response from strapi if it fails is
Invalid token: Token did not match with Strapi and Auth0 as catched in the error part.
If it would never work I would have to say I'm doing something wrong, but it works sometimes, so I would say my way is technically correct. But of course I will do something wrong.
Has everybody else had an issue like that by authentication with Auth0 and strapi and understand what I try to explain?
Here is my snippet of code (I would say exactly copied from docu with a bit personalization):
...
try {
const data = await axios({
method: 'post',
url: 'https://my.eu.auth0.com/userinfo',
headers: {
Authorization: ctx.request.header.authorization
}
});
console.debug('data from Auth0: ' + JSON.stringify(data.data));
// if you want do more validation test
// feel free to add your code here.
return await next();
} catch (error) {
return handleErrors(ctx, new Error('Invalid token: Token did not match with Strapi and Auth0'), 'unauthorized');
}
...
I hope anybody had a similar issue and any idea how this can be fixed. Maybe it is an issue in Auth0.

You'll have to update url: 'https://my.eu.auth0.com/userinfo' replacing my.eu with your actual subdomain on auth0.

Related

cookie sets in postman but not in browser on localhost

I have an issue with cookies setting in postman when I make a post request to my route to login but unfortunately when I use the same info to login via my vue frontend I don't get a set cookie header in my browser or a token but rather it just returns and API key with a value....
not sure if anyone can help explain why this might be the case. Does postman run on localhost itself by default or do they use their own servers to route requests? just wondering if maybe that's the issue?
here's the code I am using to touch the endpoint in my view endpoint
Note: I have a separate axios file with the root url so the route only shows as /login just to clarify
async handleSubmit(){
const response = await axios.post('/login', {
email: this.email,
password:this.password
});
console.log(response)
}
inside my console when logging it only returns an api key instead of a session id.
trying to dig around the postman docs to see if I can somehow use this key to get a session ID?
https://learning.postman.com/docs/sending-requests/authorization/#api-key
any help is greatly appreciated :)

How to authenticate through Graphiql playground

It's my first time using GraphQL and im trying to access the content of a given query but i can't acces this given query because of lack of permissions, in this case I have been given a username and a password to access this GraphQL api, and i'm able to get and verify the token using these credentials in GraphQL but my question is the following, how do I become authenticated in the API to be able to access the queries of the API?
My error is as follows.
"errors": [
{
"message": "You do not have permission to perform this action",
I believe this is something very basic, but I just not able to find a way to solve this issue.
Click HTTP Header and add your token as shown below:
{
"Authorization": "Bearer YOUR_TOKEN_HERE"
}
you may have to remove Bearer and only use the token, it depends on how you did authorization on the server.
This is for JWT authentication in REQUEST HEADERS on GraphiQL below:
{
"Authorization": "JWT your_jwt_access_token_here"
}
If anyone stumbles upon same issue, just sending the HTTP didn't work in my case, because I had this line in my #auth-directive:
let token = req?.cookies?.token
Which would only check token from cookies and never from request-headers where I was passing the Authorization-header.
Fixed the issue by changing it to:
let token = req?.cookies?.token ?? req?.headers?.authorization

need to mock POST request in cypress

UPDATED 9/16:
I've reworded my question. I'm trying to use cypress to test a work application that has an Angular frontend(http://localhost:4200) and a .NET Core backend (http://localhost:5000).
When the app starts, a login page loads with username and password fields. The cypress code test fills in the username and password and clicks the submit button, as show in my code below.
When the login (submit) button is clicked, it triggers a POST request to the .NET Core backend. The request submits the username and password and if the user is verified, a token comes back in response. The token is added to session storage and the user is logged in. It is this token value in the session storage that signifies the user is logged in. With the token added, the user gets redirected to the homepage.
Now the backend is NOT running. I need to simulate this POST request so the cypress test can get to the actual homepage.
I think I need to stub this POST request but I can't get this code to work. The request just aborts and looking at the console it says the request was not stubbed.
Here's my updated cypress code:
const username = 'johndoe';
const password = 'pass1234';
cy.server();
cy.get('h1').should('contain', 'Login');
cy.get('input[placeholder=Username]').type(username);
cy.get('input[placeholder=Password]').type(password);
cy.get('button[type=submit]').click();
cy.route({
method: 'POST',
url: 'http://localhost:5000/Authentication/Login',
response: {
access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' // some random characters
}
});
You might have more success if you set up the route before invoking the POST (clicking submit),
cy.server();
cy.route({
method: 'POST',
url: 'http://localhost:5000/Authentication/Login',
response: {
access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' // some random characters
}
});
...
cy.get('button[type=submit]').click();
However, if your app uses native fetch as opposed to XHR, core Cypress does not catch this type of request. You have to add a polyfill which essentially modifies the window.fetch method to allow cy.route() to succeed.
cypress.json
{
"experimentalFetchPolyfill": true
}
Please note the limitations section,
Limitations
The experimental polyfill is not foolproof. It does not work with fetch calls made from WebWorkers or ServiceWorker for example. It might not work for streaming responses and canceled XHRs. That's why we felt the opt-in experimental flag is the best path forward to avoid breaking already application under tests.

Why can't add headers to axios.get?

I'm using axios and vue.js to play with the Fortnite Tracker API.
In their documentation it's clearly said that we need to include the "TRN-Api-Key" in header.
I tested with Postman and It works.
And this is my axios function to make the request:
let url = `https://api.fortnitetracker.com/v1/profile/${this.platform}/${this.username}`;
// username and platform are from my Vue Component.
axios.get(url, {
headers: {
"TRN-Api-Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxx" // of course from my account on their website.
}
})
.then(response => console.log(response.data))
I expect the output in json like in Postman but I had a 404 Error: "Network Error".
And in the Browser Network Debug I can't see the request header 'TRN-Api-Key'.
[EDIT]
If your app is running on a server you can write a short PHP-Script and use curl in it to access the API (I think it's even possible to generate PHPcode from Postman).
Just address this script with axios and submit your platform and usernameproperties to build the right url.
Or have a look at this post alternatively. Maybe the use of an other API like #kecinotrab provided in the acceptet answer will help you too.

Keycloak API always returns 401

I'm trying to interact with Keycloak via its REST API. I have the master realm and the default admin user, and a test realm. Firstly, I get an access token for the admin account and test realm:
let data = {
grant_type : 'password',
client_id : 'test-realm',
username : 'admin',
password : 'admin'
};
let headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
axios.post(
'https://someurl.com:8080/auth/realms/master/protocol/openid-connect/token',
qs.stringify(data),
headers
)
That works ok. Then I try to make a call to create a user (or do anything else) and I get a 401 unauthorized error:
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${accessToken}`
};
data = {
rep: {
email: "test#email.com",
username: "test#email.com"
},
path: 'test-realm'
};
axios.post('https://someurl.com:8080/auth/admin/realms/test-realm/users',
qs.stringify(data),
headers
)
Is that not the correct way to include the token? Is the access token the one you use for authenticating other API calls? Shouldn't the admin account's token work for authenticating calls to other clients with the master realm? Would it be some setting in the master realm that I have to change in the admin console? Any help appreciated.
I got a 401 error because I generated the offline token by using http://localhost:8080 and then I tried to request the api by using http://keycloak:8080 which is not allowed. Unfortunately the log doesn't tell you that.
To debug JWT tokens I recommend https://jwt.io/
Is that not the correct way to include the token?
This is a correct way.
You just do something incorrectly.
Please, refer for an example from keycloak-request-token Node.js module:
https://github.com/keycloak/keycloak-request-token/blob/master/index.js#L43
You use
client_id : 'test-realm'
but there is
client_id: 'admin-cli'
there.
Also, to create a user, you should use
'Content-Type': 'application/json'
You can refer for Node.js examples of Keycloak REST API here:
https://github.com/v-ladynev/keycloak-nodejs-example/blob/master/lib/adminClient.js
Examples of other useful stuff like:
custom login
storing Keycloak token in the cookies
centralized permission middleware
can be found in the same project: keycloak-nodejs-example
I fixed it by enabling the below "Service Accounts Enabled" button under Settings for admin-cli
I had this issue and solved it by making sure that there is no more than 1 minute between the first and the second API request. So, if you are doing this manually (2 curl requests), the token may expire and you may get error 401. Nevertheless, you should use admin-cli as mentioned above.
I came this issue recently and after struggling for a while i figured. using a realm name containing white spaces will trigger 401 unauthorized error when interacting with via SDKs or API.
IN SUMMARY:
change: realm name
to: realm-name