I have been using passport.js. It works and I am able to get the oauth_token and Verifier easily from APIs.
In passport.js each API has a strategy which basically decide how to communicate with that API server. At the end a callback to get returned user profile.
But I saw no way to use oauth_token to get the profile myself. Its a one time shot at the end of Oauth authentication to save data in session or db.
Is there any way I can use my oauth_token to directly access the user profile any time usingpassport methods.
In prototype I saw userProfile function which does what I need but its a private method somehow. I don't know how to use it
Update 1
I have been scavenging the git repo for passport.js , I come to know they use the "node-oauth" to manage calls to the API servers. This is available in any strategies _oauth.
But I am not aware what calls to make to get resource token. Also I have to initiate all API calls in callbacks step by step to imitate the token access calls. Is there any standard way to do this.
Without digging into the code (but having used Passport before) I'm assuming that the oauth_token is being stored with the user data in your database. You may have to access your database models directly in order to get the token, then you can use it with the provider APIs to get access to the information you need.
Visit following page to get a grasp of how to use the _oauth property.
https://github.com/ciaranj/node-oauth
It works like this:
oauth.get(
'https://api.twitter.com/1.1/trends/place.json?id=23424977',
'your user token for this app', //test user token
'your user secret for this app', //test user secret
function (e, data, res){
if (e) console.error(e);
console.log(require('util').inspect(data));
done();
});
In case you implement your own OAuth1.0 strategy you easily could overwrite
following method to implement your own logic for fetching the profile data from the remote OAuth server:
/**
* #overwritten
* #method userProfile
* #class OAuth1Strategy
* #description used by OAuth1Strategy class while authenticating
* to get the user profile from the server
*/
OAuth1Strategy.prototype.userProfile =
function(token, tokenSecret, params, done) {
this._oauth.get(
config.profileUrl,
token,
tokenSecret,
function (e, data, res){
if (e) console.error(e);
console.log(require('util').inspect(data));
done(e, data);
});
};
Related
Hey im implementing authentication using NodeJS expressJS mongoDB / React native
is it okay to have a lot of variables in the token object like this example ?
const token = jwt.sign(
{
userId: user._id,
isAdmin: user.isAdmin,
isBanned:user.banned.isBanned
},
process.env.TOKEN_KEY,
{
expiresIn: "24H",
}
);
I added the isBanned one so i can check for it directly when the token goes to the frontend so i won't have to fetch for the user data again to get it !
Is this the best way to check if the user is banned ?
and Finally is it okay to put up to 3 variables on the token
For security reasons, it's not safe to store users datas in a JSON Web Token.
Typically you should only store the minimum datas needed to identify your user, meannig an ID.
You should also, if possible, use an unpredictable ID because numeric IDs are predictable.
The best is to have an alphanumeric uniq ID.
If you need to get some extra information once you user login, you can easilly issue a request to your API to retrieve informations...
Don't forget that token is given to the client by the server after a successfull login to avoid authenticate user at each request, not for retrieving informations.
I am working on Excel Web Add-In. I am using OfficeDev/office-js-helpers library for authenticating user. Following code is working fine. But I don't know how to get user's email, user name etc.
Is there any function available in OfficeDev/office-js-helpers through which I can get user info ?
if (OfficeHelpers.Authenticator.isAuthDialog()) {
return;
}
var authenticator = new OfficeHelpers.Authenticator();
// register Microsoft (Azure AD 2.0 Converged auth) endpoint using
authenticator.endpoints.registerMicrosoftAuth('clientID');
// for the default Microsoft endpoint
authenticator
.authenticate(OfficeHelpers.DefaultEndpoints.Microsoft)
.then(function (token) {
/* My code after authentication and here I need user's info */ })
.catch(OfficeHelpers.Utilities.log);
Code sample will be much helpful.
This code only provides you the token for the user. In order to obtain information about the user, you'll need to make calls into Microsoft Graph API. You can find a full set of documentation on that site.
If you're only authenticating in order to get profile information, I'd recommend looking at Enable single sign-on for Office Add-ins (preview). This is a much cleaner method of obtaining an access token for a user. It is still in preview at the moment so it's feasibility will depend on where you're planning to deploy your add-in.
Once you have the Microsoft token, you can send a request to https://graph.microsoft.com/v1.0/me/ to get user information. This request must have an authorization header containing the token you got previously.
Here is an example using axios :
const config = { 'Authorization': `Bearer ${token.access_token}` };
axios.get(`https://graph.microsoft.com/v1.0/me/`, {
headers: config
}).then((data)=> {
console.log(data); // data contains user information
};
I'm trying to keep things simple and using auth0-js WebAuth to authenticate users. However, as there is a redirect involved, I'm not in control of the sign-up functionality at that point.
My specific use-case is to call a createUser graphql mutation using Graphcool to create a user in my database, but I only want to do this if the user is a new user, obviously.
MY QUESTION: Using auth0-js, is it possible to identify if a user is a new or existing user in my client application after the redirect from Auth0 back to my client application (assuming authentication is successful)?
There are two general approaches here, and both require you to persist the Auth0 token in local storage after receiving it. You can use a middleware for your GraphQL client that checks local storage for a token for every request and includes it as the Authorization: Bearer <token> header if present.
Let's now look at the two approaches.
Always try to create the user
Trying to create the user using the createUser mutation as soon as receiving the token is a fairly simple approach. This is how the mutation looks like:
mutation signUp($token: String!) {
createUser(authProvider: {
auth0: {
idToken: $token
}
}) {
id
}
}
Now, if the token is valid and matches the configuration of the Auth0 integration in Graphcool, there are two possible scenarios. Note, a token corresponds to a user if the auth0UserId it embeds matches.
there is already a registered user corresponding to the token. In this case, a GraphQL error Code 3023: CannotSignUpUserWithCredentialsExist will be returned (compare with the error reference documentation). In your application you can catch this error to proceed normally.
there is no registered user yet corresponding to the token. The createUser mutation will return id and all is good!
Check if the user is already signed in
If you have a more elaborate sign up flow, you might want to redirect your users to a sign up form, which is not really possible with the first approach. Instead, we can check if the currently used token corresponds to a registered user before proceeding. You can use the user query to do that:
query {
user {
id
}
}
Again, there are the same two scenarios as above:
there is already a registered user corresponding to the token. In this case, a the query returns a user object with the corresponding user id. So we can proceed the flow in the app normally.
there is no registered user yet corresponding to the token. The date returned from the user query will be null, so we need to call the createUser mutation, or switch to a sign up form or similar.
Compare this to this FAQ article in the Graphcool documentation.
In that case, the simplest solution will be to use auth0 rule and use context.stats.loginsCount field to detect the user is new or not.
https://auth0.com/docs/rules/references/context-object
You can add context.stats.loginsCount field value as a custom claim in the token using rule. Therefore, in your application, you can make a HTTP request to /userinfo endpoint to get the token data.
function (user, context, callback) {
const count=context.stats.loginsCount;
context.idToken["http://mynamespace/logincounts"] = count;
callback(null, user, context);
}
https://auth0.com/docs/api-auth/tutorials/adoption/scope-custom-claims
If the counts are equal to 1, create the user in your DB.
I've been working on this for the past day and can't seem to figure it out. I am using this Passport-Soundcloud to implement a soundcloud authentication. However what I don't understand is how I can get, and pass an authentication token to a front-end button push to like a sound.
My front-end code looks like:
function allowLike(){
$('.queueTrack').off('click').on('click', function(user){
console.log('clicked');
SC.put('/me/favorites/' + 21928809);
consol.log('sound liked')
});
};
Whenever I try to login through my app using the /login route, it works as expected and redirects me to my homepage. The problem is that I don't know how to get the oauth token from the passport-soundcloud so I can implement it into the front-end click event.
My routes followed the passport-soundcloud instructions and seem to work, but I can't figure out how to get the oauth token...
Any ideas? I'm totally lost on this.
So, I'm not familiar with the specific details of the soundcloud api. But if it follows the basic patterns of popular oauth apis. Then you'll want to do something like this.
User arrives at your site without a cookie
they authorize your app using oauth
when the user is redirected back to your app, SoundCloud will give you an access key for this user. Store this value, in a database or a cache or in memory. But most importantly, you must create a cookie on that users browser. So that when they return you can lookup the access key again.
When the user clicks like, lookup the accesskey on the backend and hit SoundCloud api with that token.
In the initial oauth flow....
function(accessToken, refreshToken, profile, done) {
User.findOrCreate({
soundcloudId: profile.id,
token: accessToken // <--- store the token!
}, function (err, user) {
return done(err, user);
});
}
then when they click like
app.put('/me/favorites/12345' function(req, res) {
var id = req.user.id; // <--- passport and connect session saved the user id for you
// lookup the token in your database
// use the token to hit the soundcloud api
})
I hope this make some kind of sense. This is completely untested pseudo code.
Can I access Google Analytics data using a service account in a client-side application? If not, are there other ways of achieving the same outcome?
Must be entirely client-side, and must not require users to authenticate (hence the desire to use a service account).
Yes you can in https://code.google.com/apis/console make sure you say that its a Service account it will give you a key file to download. With that you dont need a user to click ok to give you access.
For a service acccount to work you need to have a key file. Anyone that has access to that key file will then be able to access your Analytics data. Javascript is client sided which means you will need to send the key file. See the Problem? You are handing everyone access to your account. Even if you could get a service account to work using javascript for security reasons its probably not a very good idea.
You can use the official (and alpha) Google API for Node.js to generate the token. It's helpful if you have a service account.
On the server:
npm install -S googleapis
ES6:
import google from 'googleapis'
import googleServiceAccountKey from '/path/to/private/google-service-account-private-key.json' // see docs on how to generate a service account
const googleJWTClient = new google.auth.JWT(
googleServiceAccountKey.client_email,
null,
googleServiceAccountKey.private_key,
['https://www.googleapis.com/auth/analytics.readonly'], // You may need to specify scopes other than analytics
null,
)
googleJWTClient.authorize((error, access_token) => {
if (error) {
return console.error("Couldn't get access token", e)
}
// ... access_token ready to use to fetch data and return to client
// even serve access_token back to client for use in `gapi.analytics.auth.authorize`
})
If you went the "pass the access_token back to client" route:
gapi.analytics.auth.authorize({
'serverAuth': {
access_token // received from server, through Ajax request
}
})