I am new in Node.js. I am using express, passport, passport-oauth2 strategy for authentication for my react application.
My react application is running on 'https//localhost:8060'
My Passport.js auth service is running on 'http://localhost:8080'
Below is the passport.js strategy configuration present in my node service index.js
passport.use(
new OAuth2Strategy(
{
authorizationURL: 'https://idp-portal-URL', // IDP portal url
tokenURL: 'https://token.oauth2', // token URL
callbackURL: 'https://localhost:8060/auth', // **REACT application call back URL**
clientID: clientCreds.clientID,
clientSecret: clientCreds.clientSecret,
scope: 'openid profile',
},
function(accessken, refreshToken, user, profile, done) {
const ca = user.id_token;
return done(null, user);
},
),
);
Then authenticating below route: This is route which i am calling from my React application e.g: 'http://localhost:8080/login'
app.get(
'/login',
passport.authenticate('oauth2', { failureRedirect: '/failed' }),
function(req, res, next) {
next();
const config = {
method: 'post',
url: `https://idp-a/authorization.oauth2?token=${req.user.access_token}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
data: {
client_id: clientCreds.clientID,
client_secret: clientCreds.clientSecret
},
};
axios(config)
.then(function(response) {
res.redirect(`https://localhost:8060/#/auth?ssoParams=${queryParam}`);
})
.catch(function(error) {
console.log(error);
});
// Successful authentication, redirect home.
},
);
with this above code user able to successfully authenticate and redirecting back to my react application URL which is configured in as callback URL with appending auth code in query param. like below:
"https://localhost:8060/auth?code=***************"
But before that in node service itself I want to retrieve access token using the auth code received in query param.
How can I retrieve access token using auth code by making API call and then redirect back to my react application with access code. The axios call which I wrote in call back function is not executing and nothing printing in console or no error.
Please help here, will appreciate your help.
Related
So, I'm having a SPA which has Okta implemented for authentication. According to the Okta policy that is set up in place, the user(s) log in with credentials (email and password) and then are prompted to validate with a magic link or code (both sent to their primary email address). I'm trying to get around this and programmatically login through API
What I've tried so far:
a POST Request to the /api/v1/authn with the username and password (which returns a session token)
then a GET request to /oauth2/default/v1/authorize with the clientID,sessionToken,redirectUri,scope which should return the access and id tokens from my understanding...
This last request just redirect back to the login page.
Cypress.Commands.add('oktaLogin', () => {
const optionsSessionToken = {
method: 'POST',
url: `https://${Cypress.env('okta_domain')}/api/v1/authn`,
body: {
username: Cypress.env('okta_username'),
password: Cypress.env('okta_password'),
options: {
warnBeforePasswordExpired: 'true'
}
}
}
cy.request(optionsSessionToken).then(response => {
const sessionToken = response.body.sessionToken;
const qs = {
client_id: Cypress.env('okta_clientid'),
redirect_uri: `https://${Cypress.env('baseURL')}/callback`,
code_challenge_method: 'S256',
responseType: ['id_token','token'],
scope: ['openid', 'profile', 'email'],
sessionToken: sessionToken,
}
cy.request({
method: 'GET',
url: `https://${Cypress.env('okta_domain')}/oauth2/default/v1/authorize`,
form: true,
followRedirect: true,
qs: qs
}).then(response2 => {
//tokens should be available here?
cy.log(response2.body)}) //returns HTML back to login.
});
})
I'm a trying to make a route accessible only if you are authenticated with JWT using below middleware but I can't seem to find a way to pass the token in the get request from client side ?
It works fine on postman and I if using a fetch from client side it won't redirect me to the page I want to go
auth.js
async function (req, res, next) {
const token = req.header('x-auth-token');
if (!token) {
return res.status(401).json({ msg: 'Forbidden' });
}
try {
const decoded = jwt.verify(token, process.env.TOKEN_SECRET);
req.user = decoded.user;
next();
} catch (e) {
return res.status(401).json({ err: 'fail' });
}
};
server side
router.get('/', auth, function (req, res, next) {
res.render('pages/person');
});
You can simply attach your token to the headers in the request and sent it with get or even 'delete` method.
for example, in the fetch method you can attach your token in this way in your client side:
fetch('URL_GOES_HERE', {
method: 'post',
headers: new Headers({
'Authorization': YOUR_TOKEN,
'Content-Type': 'application/x-www-form-urlencoded'
}),
});
Now, you can retrieve the token in the node app:
const token = req.headers.authorization || "";
I am very new to the Google OAUth2.0 authentication and thus my question sounds like dumb. However, I am stuck with this problem quite a time and need your input to solve it.
I was integrating the Globus login within my app. Globus login using Google OAuth-2 protocol for authentication. According to the Globus Auth developer guide, I successfully redirect the app to their authorization service, the user can put their credential to authenticate, and the app receives the code returned from the Globus Auth server upon successful authentication. Next step is sending the code to the Token endpoint to get the access token. I used the following code:
var querystring = require('querystring');
export const logInGlobus = (payload) => {
let tokenUri = encodeURIComponent(payload.redirect_uri);
let client_id = 'out app client id'
let client_secret = 'client secret generated for authentication'
let cred = btoa(client_secret);
return axios.post('https://auth.globus.org/v2/oauth2/token',
querystring.stringify({
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: tokenUri,
client_id: client_id
}),
{
headers:{
Authorization: 'Basic '+ cred,
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return{
res: response,
success: true
}
})
.catch(err => {
return{
res: err,
success: false
}
})
}
I am getting 401 {"error":"invalid_client"} code for this post request from the server. What am I missing?
N.B: I have tried without client secret, client id, not encoding redirect URL. No luck so far>
I would really appreciate your effort if you show me some light. Thanks for your time.
====Edited====
The error from the console at the browser is attached
I solved the problem. I had to put the client secret at the body of the post request. The following code resolves my problem.
var querystring = require('querystring');
export const logInGlobus = (payload) => {
let client_id = 'app client id'
let client_secret = 'client secret generated for authentication'
return axios.post('https://auth.globus.org/v2/oauth2/token',
querystring.stringify({
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: payload.redirect_uri,
client_id: client_id,
client_secret: client_secret
}),
{
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return{
res: response,
success: true
}
})
.catch(err => {
return{
res: err,
success: false
}
})
}
I want to automate the OAuth 2.0 token automatically via javascript. Is there any way I can do that and obtain the token to use it in the artillery scrtips.
For the OAuth token generation I have below details:
Auth URL
Client ID
Scope
It is done by client authentication credentials.
Below is the sample code I am using to generate the token:
var ClientOAuth2 = require('client-oauth2')
var Auth = new ClientOAuth2({
clientId: 'ClientID',
accessTokenUri: 'https://Auth_URL/v2.0/token',
authorizationUri: 'https://Auth_URL/v2.0/authorize',
redirectUri: 'https://Auth_URL/',
scope: 'api://Scope/access_as_user'
})
Auth.owner.getToken('Username', 'password')
.then(async (user) => {
await console.log(user) //=> { accessToken: '...', tokenType: 'bearer', ... }
}).catch((e) => { console.log('error show',e); })
.finally( () => console.log('end'));
You can declare your custom JS files which will be triggered every time before the request:
Your YAML file can be like here:
config:
target: "https://baseUrl.com"
phases:
- duration: 60
arrivalRate: 100
processor: "./customFile.js"
scenarios:
- flow:
- post:
url: "/pathInYourApi"
headers:
Content-Type: "application/json"
Accept: application/json
json: {}
beforeRequest: "beforeRequest"
and then your customFile.js script:
module.exports = {
beforeRequest: beforeRequest,
};
function beforeRequest(requestParams, context, ee, next) {
// Call your OAuth client, and after you obtain token you can assign it to requestParams Authorization header
// eg. requestParams.headers.Authorization = `Bearer + ${token}`
return next(); // MUST be called for the scenario to continue
}
I am trying to achieve LinkedIn sign in using their API provided by Oauth2.0
According to docs - https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow?context=linkedin/consumer/context
I am able to get access code (1 step). Afterwards I stuck on completing new request with error (to get an accessToken) - https://gyazo.com/abe24d7294aa4c1b9d8be9a101747ee2
Although I did configure my redirect URI in LinkedIn dev dashboard - https://gyazo.com/c533a589465042342d79438eab02d2a2
I've tried querystring.stringify method from query-string package
function trigerLogin() {
const accessToken = localStorage.getItem('AccessCode');
if (!accessToken) {
window.open('https://www.linkedin.com/uas/oauth2/authorization?response_type=code&state=DCEeFWf45A53sdfKef424&client_id=*************&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fcallback&scope=r_liteprofile+r_emailaddress', '_blank', 'top=100, left=200, height=500, width=500');
}
axios.post('https://www.linkedin.com/oauth/v2/accessToken', querystring.stringify({
client_id: '*************', // for safety reasons
grant_type: 'authorization_code',
code: accessToken,
redirect_uri: 'http://localhost:4000/callback',
client_secret: '**************' // for safety reasons
}))
.then(function (response) {
console.log(response);
})
.catch(error => {console.log(error)})
}
So I cannot get a response with a token with which I can work further
Thank you in advance!