OAuth2 - Got token, how to send with POST request? - node.js

Working with a vendor with minimal API and new to OAuth2. Using npm packages oauth and request.
Creating a node module which would post data from a database to the server's API.
I've got the authorization token, but now I'm unsure how to send that with the data post request. The vendor server is responding with a simple Cannot POST /accounts/import.
So - how do I send the OAuth2 token back with the post data to the server?
var request = require('request'),
clcreds = require('../../creds/creds.js');
var OAuth = require('oauth');
var OAuth2 = OAuth.OAuth2;
var oauth2 = new OAuth2(clcreds.clientId, clcreds.clientSecret, 'https://URL.com/', null, 'token', null);
oauth2.getOAuthAccessToken('', {
'grant_type': 'client_credentials'
}, function(e, access_token, refresh_token, results) {
console.log(e, access_token, refresh_token, results);
request.post('https://URL.com/accounts/import', {
"accounts": [{
...
}]
}, function(e, r, body) {
//returns Cannot POST /accounts/import
})
})

Most resource servers support RFC 6750, 2.1. Authorization Request Header Field. If your server supports it, you can pass an access token to the server by adding Authorization header like below.
Authorization: Bearer YOUR-ACCESS-TOKEN
If your server does not support any means defined in RFC 6750, you have to ask the implementor of the server about how to pass an access token to the server.

Related

Invalid token provided in oidc-provider accessing UserInfo enpoint

I started using OAuth2 server with oidc in node js. Github link
My goal is simple, to access https://myserver/me which is UserInfo endpoint.
While trying to learn how to use the server I also used this guide enter link description here
Where I found that I could create token by sending request to endpoint /token.
Into the configuration I added this code(full server code is below):
{
client_id: 'test_oauth_app',
client_secret: 'super_secret',
grant_types: ['client_credentials'],
redirect_uris: [],
response_types: [],
}
In postman I was able to get my the access_token by this request
POST /token
Headers:
Content-Type: application/x-www-form-urlencoded
Authorization: Basic dGVzdF9vYXV0aF9hcHA6c3VwZXJfc2VjcmV0
Body:
grant_type=client_credentials&scopes=api1
I get this as a response:
{
"access_token": "zdjmZo7_BQSIl4iK9IMcBbKffxGO-wQ3jLzzQXTlyws",
"expires_in": 600,
"token_type": "Bearer"
}
When I checked the token by /token/introspection I found out that the token equals to jti.
So I think it actually returns token_id and by that I cannot access /me endpoint.
Here is the whole sample of server that I use:
const { Provider } = require('oidc-provider');
const configuration = {
features: {
introspection: { enabled: true },
clientCredentials: { enabled: true },
userinfo: { enabled: true },
jwtUserinfo: { enabled: true },
},
formats: {
AccessToken: 'jwt',
},
clients: [{
client_id: 'test_oauth_app',
client_secret: 'super_secret',
grant_types: ['client_credentials'],
redirect_uris: [],
response_types: []
}],
scopes: ['api1']
};
const oidc = new Provider('http://localhost:3000', configuration);
oidc.proxy = true
// express/nodejs style application callback (req, res, next) for use with express apps, see /examples/express.js
oidc.callback
// koa application for use with koa apps, see /examples/koa.js
oidc.app
// or just expose a server standalone, see /examples/standalone.js
const server = oidc.listen(3000, () => {
console.log('oidc-provider listening on port 3000, check https://localhost:3000/.well-known/openid-configuration');
});
The proxy is set to true because I have https set up on apache redirecting to this server.
I tried to change response_types, but than it required redirect_uri which I do not want to have in my scenario.
Here is the request I am trying to post it like so:
POST /me
Headers:
Content-Type: application/json
Authorization: Bearer zdjmZo7_BQSIl4iK9IMcBbKffxGO-wQ3jLzzQXTlyws
The response:
{
"error": "invalid_token",
"error_description": "invalid token provided"
}
Did anyone have a similar problem? I found almost the same problem here
but with no solution, unfortunately.
In case someone encounters the same problem. I was able to solve it.
I did not have enough information and I did not know what client_credentials grant type does.
It actually does not authorize the user, but rather some app. So you have no info about the user, hence you cannot get data about the user through the userinfo endpoint.
So if you want to get info about the user, you probably want to use grant type authorization_code.
I found a page where a lot of things is written pretty clearly, so if you are starting with
OAuth server you might want to give this a try.
https://oauth2.thephpleague.com/authorization-server/auth-code-grant/

Microsoft-Graph token using request is to small

I'm trying to get the access token for my Microsoft-Graph application using request to send a POST request.
The problem is that the token i get as a response is only 1188 characters long. While the token i get when i use Postman is 1461 characters long. Every time i send a request it generates a brand new token, but the one i get through request in nodejs is always 1188 and the one in postman is always 1461.
I have tried different things such as generating a new app api id in Microsoft Azure, but it keeps giving the same results.
This is my code, i took out sensitive information though by replacing it with the word CENSORED.
I'm using the EXACT same request parameters in Postman
const endpoint = "https://login.microsoftonline.com/CENSORED/oauth2/token";
const requestParams = {
client_id: "CENSORED",
client_secret: "CENSORED",
resource: "https://graph.windows.net",
grant_type: "client_credentials"
};
let accessToken = await
request.post({
url: endpoint,
form: requestParams
}, function (err, response, body) {
if (err) {
console.log("error");
} else {
console.log("Body=" + body);
let parsedBody = JSON.parse(body);
if (parsedBody.error_description) {
console.log("Error=" + parsedBody.error_description);
} else {
getCalendarEvents(parsedBody.access_token);
}
}
});
Postman returns an 1461 characters long access token and nodejs request only returns a 1188 characters long access token.
This is what i'm using in Nodejs: https://www.npmjs.com/package/request
The resource https://graph.windows.net is for the legacy Azure AD Graph API. This is a completely separate API from the Microsoft Graph. For the Microsoft Graph, the resource should be https://graph.microsoft.com:
const endpoint = "https://login.microsoftonline.com/{tenant}/oauth2/token";
const requestParams = {
client_id: "{clientid}",
client_secret: "{clientsecret}",
resource: "https://graph.microsoft.com",
grant_type: "client_credentials"
};
Apparently the resource parameter should be https://graph.microsoft.com instead of https://graph.windows.net.

Auth0 + JWT + NodeJS + Express End-user authentication (Login)

Has been almost a year that I switch to Auth0 in order to manage my customer's access to the dashboard of my application. Nowadays I need to implement access for a RESTFULL API.
If I follow the instructions in order to secure the NodeJS app using JWT it works like a charm. The issue is that I am not properly sure on the implementation for the end user in order to get the token needed for access this API.
I thought of creating the tokens on the dashboard or just use a server side implementation for the login/authentication. I did the last using the access to my own database before and worker amazingly. My issue is that I am not completely sure on how to do it for the end user using Auth0.
Anyone implemented a RESTfull API that has login using Auth0 before in order to get the JWT token ? Would my great to hear your thoughts.
The solution was to use a different approach.
There is an Auth0 endpoint that uses the user and password for the user in order to login with the service. This way I can get the id of the authenticated user and a JWT token that I can use to validate future requests.
https://auth0.com/docs/api/authentication#resource-owner-password
This flow should only be used from highly trusted applications that cannot do redirects. If you can use redirect-based flows from your apps we recommend using the Authorization Code Grant instead.
router.post('/login', function (req, res, next) {
var options = {
method: 'POST',
url: process.env.AUTH0_URL_OAUTH,
headers: {
'Cache-Control': 'no-cache',
'Content-Type': 'application/json'
},
body: {
grant_type: 'password',
username: req.body.username,
password: req.body.password,
audience: process.env.AUTH0_AUDIENCE,
scope: process.env.AUTH0_SCOPE,
client_id: process.env.AUTH0_CLIENT_ID,
client_secret: process.env.AUTH0_CLIENT_SECRET
},
json: true
};
request(options, function (error, response, body) {
if (error) {
res.sendStatus(500); //We could not connect to the service
} else {
if (body.error) {
console.log(body);
res.status(400);
res.send({
error: body.error_description // There was an error with the user or password
});
} else {
console.log(body);
/**
* Everything went well. We return the JWT
*/
res.send({
access_token: body.access_token,
expires_in: body.expires_in,
token_type: body.token_type
});
}
};

not able to get user info

bellow is my node js script to get google user details using accessToken
var accessToken = req.body.accessToken;
console.log(accessToken)
var google = require('googleapis');
//google api
var plus = google.plus('v1');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(
config.google.clientID,
config.google.clientSecret,
config.google.redirect_uri
);
oauth2Client.setCredentials({access_token: accessToken});
plus.people.get({
userId: 'me',
auth: oauth2Client
}, function (err, response) {
// handle err and response
if (err) {
reject(err)
} else {
console.log(response);
resolve(response)
}
});
need to get google login user details using accessToken. what is wrong in code?
The most likely cause is the user in question has not created a google+ profile. Here are a few more options.
I am not sure what information you are trying to get but the best way to get user info is to authecate a user using the profile scope then request the data directly of the user info endpoint
Request
GET /userinfo/v2/me HTTP/1.1
Host: www.googleapis.com
Content-length: 0
Authorization: Bearer uzG4XqnvucBFk3jylgxnbtNhoOt2wCc3QvUcjk7PZhJ5m6G7ibtlBwbAQntJjJtLsxZfoDjhbASpzLmcFnlZ9o4qoMd2fCV2eRb4O5XrKRAXC
Response
{
"family_name": "Lawton",
"name": "Linda Lawton",
"picture": "https://lh5.googleusercontent.com/-a1CWlFnA5xE/AAAAAAAAAAI/AAAAAAAAl1I/UcwPajZOuN4/photo.jpg",
"locale": "en",
"gender": "female",
"link": "https://plus.google.com/+LindaLawton",
"given_name": "Linda",
"id": "117200475532672775346"
}
You can also go though the google people api using the same profile scope
GET /v1/people/me HTTP/1.1
Host: people.googleapis.com
Content-length: 0
Authorization: Bearer NuzG4XqnvucBFk3jylgxnbtNhoOt2wCc3QvUcjk7PZhJ5m6G7ibtlBwbAQntJjJtLsxZfoDjhbASpzLmcFnlZ9o4qoMd2fCV2eRb4O5XrKRAXC
But this endpoint reads from Google+ so if the user has not filled anything out on their Google+ profile you wont see much data here.
You can use request module to get the user detail on your node server.
But Before requesting the user data, make sure you have authorized the API by giving it the desired scope. In your case, you need to give https://www.googleapis.com/auth/userinfo.profile in the scope.
When you receive your accessToken, use that token to call this google api
https://www.googleapis.com/oauth2/v1/userinfo
const request = require('request');
// use any api you want to call.
request({
url: 'https://www.googleapis.com/oauth2/v1/userinfo',
method: 'GET',
headers: {
'Authorization': `Bearer ${YourAccessToken}`,
'Accept': 'application/json'
}
}, function(err, response, _user) {
console.log('User Data', _user);
})
I hope this will solve your problem. If still there is some problem, you can test your Google APIs on OAuth 2.0 Playground

How to implement JSON web token on front end side?

I am working on a nodejs express application. I used Passport's JSON web token for authentication. I have successfully created a JSON web token and it's working fine in Postman and also verifies when token passes into authorization. But I stuck on front-end side.
app.get('/profile',passport.authenticate('jwt',{session:false}),function(req,res){
// res.json({user:user.req});
// console.log(req.query.token);
res.json('bingo u cant see this without token')
});
How do I send the token in the headers like I did in Postman to this (/profile) route, i.e how to implement token on front end side so that it first checks token?
It depends on the kind what you are using to make your request at the frontend
if you are using ajax, do something like this
$.ajax({
type: 'POST',
url: url,
headers: {
"authToken":"your token" //you could save it in localstorage when recieved
}
//OR
//beforeSend: function(xhr) {
// xhr.setRequestHeader("My-First-Header", "first value");
// xhr.setRequestHeader("My-Second-Header", "second value");
//}
})
and if it's axios try doing it like this
post(url, {
headers: { authToken: token }
})

Resources