Giter Site home page Giter Site logo

passport-facebook-token's Introduction

passport-facebook-token

Build Status Coverage Downloads Downloads

Passport strategy for authenticating with Facebook access tokens using the OAuth 2.0 API.

This module lets you authenticate using Facebook in your Node.js applications. By plugging into Passport, Facebook authentication can be easily and unobtrusively integrated into any application or framework that supports Connect-style middleware, including Express.

Installation

npm install passport-facebook-token

Usage

Configure Strategy

The Facebook authentication strategy authenticates users using a Facebook account and OAuth 2.0 tokens. The strategy requires a verify callback, which accepts these credentials and calls done providing a user, as well as options specifying a app ID and app secret.

const FacebookTokenStrategy = require('passport-facebook-token');

passport.use(new FacebookTokenStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    fbGraphVersion: 'v3.0'
  }, function(accessToken, refreshToken, profile, done) {
    User.findOrCreate({facebookId: profile.id}, function (error, user) {
      return done(error, user);
    });
  }
));

Authenticate Requests

Use passport.authenticate(), specifying the 'facebook-token' strategy, to authenticate requests.

app.post('/auth/facebook/token',
  passport.authenticate('facebook-token'),
  function (req, res) {
    // do something with req.user
    res.send(req.user? 200 : 401);
  }
);

Or using Sails framework:

// api/controllers/AuthController.js
module.exports = {
  facebook: function(req, res) {
    passport.authenticate('facebook-token', function(error, user, info) {
      // do stuff with user
      res.ok();
    })(req, res);
  }
};

Client Requests

Clients can send requests to routes that use passport-facebook-token authentication using query params, body, or HTTP headers. Clients will need to transmit the access_token and optionally the refresh_token that are received from facebook after login.

Sending access_token as a Query parameter

GET /auth/facebook/token?access_token=<TOKEN_HERE>

Sending access token as an HTTP header

Clients can choose to send the access token using the Oauth2 Bearer token (RFC 6750) compliant format.

GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer base64_access_token_string

Optionally a client can send via a custom (default access_token) header.

GET /resource HTTP/1.1
Host: server.example.com
access_token: base64_access_token_string

Sending access token as an HTTP body

Clients can transmit the access token via the body

POST /resource HTTP/1.1
Host: server.example.com

access_token=base64_access_token_string

Credits

License

MIT License

passport-facebook-token's People

Contributors

cgault avatar dependabot[bot] avatar drudge avatar etler avatar evenbrenna avatar fabriziomoscon avatar ghaiklor avatar kamote avatar kenleytomlin avatar lifeofbrian avatar maximization avatar morenoh149 avatar nessche avatar niftylettuce avatar phil-taylor avatar robertdimarco avatar rodrigok avatar tato123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

passport-facebook-token's Issues

oauth2 warn

createCredentials() is deprecated, use tls.createSecureContext instead
node 0.12.2

Do you have an example?

I am new to passport and passport-facebook-token usage. The passport-facebook-token fits my usecase perfectly. Just an example my give the needed push

Failed to serialize user into session

What could I do wrong:

Error: Failed to serialize user into session
    at pass (C:\Users\gpolis\Documents\work\telemed\web\node_modules\passport\lib\authenticator.js:277:19)
    at Authenticator.serializeUser (C:\Users\gpolis\Documents\work\telemed\web\node_modules\passport\lib\authenticator.js:295:5)
    at IncomingMessage.req.login.req.logIn (C:\Users\gpolis\Documents\work\telemed\web\node_modules\passport-google-oauth\node_modules\passport-oauth\node_modules\passport\lib\passport\http\request.js:43:29)
    at FacebookTokenStrategy.strategy.success (C:\Users\gpolis\Documents\work\telemed\web\node_modules\passport\lib\middleware\authenticate.js:228:13)
    at verified (C:\Users\gpolis\Documents\work\telemed\web\node_modules\passport-facebook-token\lib\passport-facebook-token\strategy.js:101:12)
    at Promise.<anonymous> (C:\Users\gpolis\Documents\work\telemed\web\server\auth\facebook\passport.js:67:20)
    at Promise.<anonymous> (C:\Users\gpolis\Documents\work\telemed\web\node_modules\mongoose\node_modules\mpromise\lib\promise.js:177:8)
    at Promise.EventEmitter.emit (events.js:98:17)
    at Promise.emit (C:\Users\gpolis\Documents\work\telemed\web\node_modules\mongoose\node_modules\mpromise\lib\promise.js:84:38)
    at Promise.fulfill (C:\Users\gpolis\Documents\work\telemed\web\node_modules\mongoose\node_modules\mpromise\lib\promise.js:97:20)

Cyclic redirection on auth page

Using LoopBack. Passport configuration:

{
  "facebook-token": {
    "module": "passport-facebook-token",
    "authorizationURL": "/auth/facebook-token",
    "tokenURL": "/auth/account",
    "clientID": 123,
    "clientSecret": "456"
  }
}

I have cycled redirect when I try to authorize.
Following parameters are added to the address of the page:
response_type=code&redirect_uri=&client_id=123

why is req.body required?

Pardon my ignorance, but why is req.body required. I am sending the access token via the query string and there is no body so when it hits the check around line 81 it fails, even thought he access token is present in the query string and is valid.

i put in a work around and check if the body exists before accessing the body.access_token property giving preference to body over querystring.

if this is valid behavior, i will fork and submit a pull request.

perhaps i am missing something in my setup of restify/passport and this strategy

Creating a session with passport-facebook-token

Node.js version : latest
Library version : latest
Passport version : latest


I am creating an API that will be used by native, mobile apps and an auth system with passport-facebook-token. In some cases, I need to log-in twice to create a session. I am testing my API with Postman. I’ve noticed that at the first call at /auth/facebook/token it creates a Cookie with a sessionId parameter and returns:

HTTP/1.1 200 OK
{
    success : true,
    message : "User logged in",
}

… but when I am trying to request a route which has the isUserAuthorized middleware (req.isAuthenticated()), it says that the user is not logged in. Then I need to call the auth/logout route and log-in again in order to make everything work correctly. The strange thing is that the auth/logout route also makes usage of the isUserAuthorized middleware. I am not sure if it’s a problem with passport-facebook-token or with my implementation, but I need to resolve this issue ASAP.

isUserAuthorized middleware:

export default ( req, res, next ) => {
    if ( req.isAuthenticated() )
        return next();

    res.status( 401 ).send( {
        success : false,
        message : "User not logged in",
    } );
};

/auth/facebook/token route:

At the begining it was a POST route, but it was not working at all. When I was trying to send POST data it was redirecting me to an unexisting url (/auth/facebook/undefined if I remember well). I am sending access_token as a query parameter now, it works fine. req.login and req.user are provided by passport:

app.get( "/auth/facebook/token", passport.authenticate( "facebook-token" ), ( req, res ) => {
    req.login( req.user, error => {
        if ( error ) {
            return res.json( {
                success : false,
                error   : error,
            } );
        }

        res.json( {
            success : true,
            message : "User logged in",
        } );
    } );
} );

/auth/logout route:

app.get( "/auth/logout", isUserAuthorized, ( req, res ) => {
    req.logout();

     res.json( {
         success : true,
         message : "User logged out",
     } );
} );

Express app config:

Just pasting stuff used by passport/etc., not all the code because it’s a big and complex class; I’ve written a super-class extending the Express.js app.

import passport from "passport";

// Used to serialize the user for the session:
passport.serializeUser( ( user, done ) => {
    done( null, user[ 0 ].dataValues.id );
} );

// Used to deserialize the user:
passport.deserializeUser( ( id, done ) => {
    Users.findById( id )
        .then( user => done( null, user ) )
        .catch( err => done( err ) );
} );

Notice that the Cookie created after requesting the /auth/facebook/token route has the same name (sessionId) as in the express-session middleware - I am not sure if this does changes something or not:

import helmet           from "helmet";
import express          from "express";
import session          from "express-session";
import bodyParser       from "body-parser";

// Allows us to create sessions:
 this.app.use( session( {
    secret : "sfda",
    resave : false,
    name   : "sessionId",
    saveUninitialized : false
} ) );

// Protect express from some well-known web vulnerabilities:
this.app.use( helmet() )

// Allows express to read `x-www-form-urlencoded` data:
this.app.use( bodyParser.urlencoded( { extended : false } ) );
this.app.use( bodyParser.json() );

// Allows basic auths with `passport.js`:
this.app.use( passport.initialize() );
this.app.use( passport.session() );

Facebook Token Strategy:

There’s no problem with this strategy - everything works just fine.

import passport              from "passport";
import FacebookTokenStrategy from "passport-facebook-token";

export default ( Users, config = {} ) => {
    passport.use( new FacebookTokenStrategy( {
        clientID        : config.facebook.clientID,
        clientSecret    : config.facebook.clientSecret,
        callbackURL     : config.facebook.callbackURL,
        profileFields   : [ "id", "birthday", "displayName", "gender", "email", "picture" ],
        scope           : [ "email", "user_birthday", "user_about_me" ],
    }, ( token, refresh, profile, done ) => {
        Users.findOrCreate( {
            where : {
                token : profile.id,
            },
            defaults : {
                name        : profile.displayName,
                email       : profile.emails[ 0 ].value,
                photo       : profile.photos[ 0 ].value,
                gender      : profile.gender,
                birthday    : profile._json.birthday,
            },
        } ).then( user => {
            done( null, user );
        } ).catch( err => {
            done( err );
        } );
    } ) );
};

I wonder what might cause this issue - the implementation seems right for me.

What's The format of object JSON?

Hello,
What's format of object son that i need to send to server? Because The server return this message for me: "JSON text did not start with array or object and option to allow fragments not set."

I am trying to use this module so in future I get the access_token from mobile devices(whether from native library or third-party SDK) and authenticate/authorize users.

For test, I am using passport-facebook for my browser-based app and it works perfectly. It brings back a token, is this the access token this module needs? Because I used all sort of access_token and I always get Unauthorized 401 error.

Please guide me to use this module as it's necessary for people who are developing mobile apps and have their backends on NodeJS+PassportJS. A simple example of getting access_token and a sample post URL with JSON would mean a lot.

Thanks.

I'm passing with this format:

{
"acess_token" = CAAX0gvob580BADKzfxvrX22ZBq4KvOZC6KN72M4BL4y1QdjKrxfNP1KFHgx0kI8BPIsESnHacqSZAu3HjGweOuaZAMG6RRcabJ0q086o5uAvHJQwu7klpN6RH682w2hhFZAhBeSBZCCkXKJLByDeasaPS8q55VFo7zKKvwPcaFlA3raozMit80r8ekZBltKgj3Bq6yAdWKHNRRBS9HZCwpC5Im9vkChXIHh7TZBuO97fytwZDZD;
}

OR

ttp://192.168.1.2:3000/auth/facebook/token?acess_token=CAAX0gvob580BALuSeZBEnZCaX1gOfBENXw8DguDhiU2ItP51fsC2T8WamyqY6KNGTi6mOLXfKOKAZBDiqzSlK3PWeTR56Ng1yR0cXXOPSTrLbprEEJZC0yMnZBGb4FKi36jaIRNJLtNgZAInTW52Pa1RKj0FHIjW72p5vHY8XcZBatwaWTvOe97sT3yySUC0EZCTtZBlNCbCWzVUqnGA6kqUCn8mPudXzxnLvjOGUZAZBZBRZBgZDZD

InternalOAuthError: Unable to fetch user profile.

I am trying to do facebook auth login using passport-facebook-token in loopback. I followed the documentation provided but i am getting the following error message when passing auth token to my api.

500 InternalOAuthError: Failed to fetch user profile
   at /media/mohit/crytek/NodeJs/Projects/partiko-backend/node_modules/passport-facebook-token/lib/index.js:152:32
   at passBackControl (/media/mohit/crytek/NodeJs/Projects/partiko-backend/node_modules/oauth/lib/oauth2.js:123:9)
   at IncomingMessage.<anonymous> (/media/mohit/crytek/NodeJs/Projects/partiko-backend/node_modules/oauth/lib/oauth2.js:143:7)
   at emitNone (events.js:91:20)
   at IncomingMessage.emit (events.js:185:7)
   at endReadableNT (_stream_readable.js:926:12)
   at /media/mohit/crytek/NodeJs/Projects/partiko-backend/node_modules/async-listener/glue.js:188:31
   at _combinedTickCallback (internal/process/next_tick.js:74:11)
   at process._tickDomainCallback (internal/process/next_tick.js:122:9)
   at process.fallback (/media/mohit/crytek/NodeJs/Projects/partiko-backend/node_modules/async-listener/index.js:450:15)

But i got this token from facebook graph api, and is a valid token. Can anyone help me?

Also if i use access token provided on my developer account here:
https://developers.facebook.com/tools/access_token/

then i am able to fetch my own user profile. I dont understand where is the problem. I tried integrating google using passport-google-plus-token..it went well, but i am not able to integrate facebook login via access token.

Include request parameters in documentation

The documentation could be improved a bit, as I didn't know that the request parameters were supposed to be formatted as:

access_token and refresh_token

I had to look into the source to find that.

Would also be good to explicitly mention that the strategy name is facebook-token for the passport.authenticate lookup.

Thanks for making this though! I had a hacked together solution for this and this is way better.

strategy for authenticating with Facebook using the code returned

Hi, I'm not sure which strategy to follow to fulfill this facebook login flow: "Login on Client, API Calls from Server" or "Login on Client, API Calls from Client or Server". Essentially the client (mobile webview) would have initiated the Ouath flow with its callback that'll receive code and then have to use another GET https://graph.facebook.com/v2.3/oauth/access_token? client_id={app-id}&redirect_uri={redirect-uri}&client_secret=app-secret}&code={code-parameter}. to get access token. Can this passport module be used for this? and also does it implement CSRF protection. Kindly point me to the right strategy/module to use?

InternalOAuthError: Failed to fetch user profile

Hi there !

I thought I've correctly setup the passport-facebook-token. But unfortunately I get this:

InternalOAuthError: Failed to fetch user profile
    at blablabla/node_modules/passport-facebook-token/lib/index.js:152:32
    at passBackControl (blablabla/node_modules/oauth/lib/oauth2.js:123:9)
    at IncomingMessage.<anonymous> (blablabla/node_modules/oauth/lib/oauth2.js:143:7)
    at IncomingMessage.emit (events.js:129:20)
    at _stream_readable.js:908:16
    at process._tickCallback (node.js:355:11)

To describe what I do: I have a cordova client application that gets (successfully) an access token and sends it to my node.js REST API (protected with passport-facebook-token) within the Authorization HTTP header like this:

Authorization: Bearer access_token

I've tried to base64 encode the token but it doesn't change anything...

What could I miss here ?

How can I get access token

I code as below
passport.use(new FacebookStrategy({ clientID: MY_CLIENT_ID, clientSecret: MY_SECRET_ID }, function(accessToken, refreshToken, profile, done) { console.log(profile); console.log(accessToken); return done(null, profile); } ));
But it doesn't work. It doesn't print any data
Can you help me

isAuthenticated() is always returning false

How would I use middleware to create a restful api authentication using token? Does anyone have a working example using passport-facebook-token? I just want to see an example where the passport-facebook-token is used to create a restful API with authentication and middlewares.
req.isAuthenticated() is always giving me false.

This is the code i have

var passport = require('passport');
var FacebookTokenStrategy = require('passport-facebook-token').Strategy;
var mongoose = require('mongoose');

passport.use(new FacebookTokenStrategy({
        clientID: 'APP_ID_GOES_HERE',
        clientSecret: 'APP_SECRET_GOES_HERE',
    }, function(accessToken, refreshToken, profile, done) {
        console.log(profile);
                    // Do stuff with the profile. You're already getting authenticated data so there's no need to double check anything! For example
                    mongoose.model('User').findOrCreate({...}, function(err, user) {
                          done(err, user);
                    })
    })
);

   app.post('/login/facebook', passport.authenticate('facebook-token', {session: false}), function(req, res) {
    // Congratulations, you're authenticated!
    return res.json({status: 'OK'});
});

Thanks

Cannot read accessToken from header!

I have the latest 0.3.2 version of passport-facebook-token from npm repo.

The access_token is currently read only from request.body & request.query.

I see you have committed code to read from headers in Github in stategy.js. Can you publish this version to npm?

500 InternalOAuthError: Failed to fetch user profile

Hi, I've got a problem, I'm new at this, when I try to send a token through this callback that I defined localhost:3000/auth/facebook-token/callback?access_token= the result is the following error:

500 InternalOAuthError: Failed to fetch user profile
at C:\adminEasy\loopback-angular-admin\node_modules\passport-facebook-token\lib\index.js:152:32
at passBackControl (C:\adminEasy\loopback-angular-admin\node_modules\oauth\lib\oauth2.js:123:9)
at IncomingMessage. (C:\adminEasy\loopback-angular-admin\node_modules\oauth\lib\oauth2.js:143:7)
at IncomingMessage.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickDomainCallback (node.js:381:11)
at process. (C:\adminEasy\loopback-angular-admin\node_modules\async-listener\index.js:19:15)

I have tested the token in Graph API Explorer of facebook, and the token is right! but I don't get it! can you help me?

InternalOAuthError: Failed to fetch user profile

Hi,
the plugin work fine when I supply a correct facebook token. But when I test it with an expired/wrong token, it throw this exception:
InternalOAuthError: Failed to fetch user profile
Is it normal ?? Why not returning just error code when the token is incorrect ??
How can I catch this exception ?? I have already added a callback to catch the exception but it was never called. I got just the exception returned from the server.

Thanks

Allow clients to specify size of profile image

Would you be willing to extend the library to allow for optionally setting the size of the profile image? Aside from type=[small, normal, album, large] the endpoint accepts width and height parameters which are rounded to the nearest available dimensions https://developers.facebook.com/docs/graph-api/reference/user/picture/. From my tests I saw that you can get a picture as big as 1520 by 1520 which results in a much better quality than the large version.

Setting accessToken?

I'm slightly confused on how to use this. If the implementation is somewhat like decribed in the post here:

jaredhanson/passport-facebook#26 (comment)

then am i correct that i should set req.body.accessToken by a POST request?

so an app.post route for passport-facebook-token with the accesstoken set by the JS SDK

and a get route for the plain passport-facebook wich provides a token by redirecting through facebook?

Facebook Account Kit integration

Hey guys any idea how I can integrate this with Facebook Account Kit (passwordless SMS/email login). In this case, I am able to fetch the access token and email/phone number but can't create the user since passport-facebook-token tries to fetch the Facebook user profile before creating the user.

Thanks a lot!

Use OAuth2 standard RFC 6750 for accepting bearer (access) tokens instead of non-standard header field

Currently the project supports receiving access tokens from a non-compliant header field access_token

this._accessTokenField = options.accessTokenField || 'access_token';

...
...

let accessToken = (req.body && req.body[this._accessTokenField]) || (req.query && req.query[this._accessTokenField]) || (req.headers && req.headers[this._accessTokenField]);

However to be compliant to the OAuth2 spec (which this library seems to support given the fb api version) by default the library should accept a header called Authorization with the following format:

Authorization: Bearer <<access_token_goes_here>>

i.e.

Authorization: Bearer mF_9.B5f-4.1JqM

The biggest change would be receiving and parsing the access token and ignoring the string "Bearer"

I would be willing to make this change, just want to make sure that its acceptable and there isn't any reason not to.

Passport is undefined!

Hello guys, i'am new to nodeJS and i picked loopback as my android and iOS apps backend, I'am implementing Facebook login and apparently passport-facebook-token is what i should use to authorise users after the mobile authentication.

I've installed passport-facebook-token and added in server/server.js the following code

var FacebookTokenStrategy = require('passport-facebook-token');

passport.use(new FacebookTokenStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET
  }, function(accessToken, refreshToken, profile, done) {
    User.findOrCreate({facebookId: profile.id}, function (error, user) {
      return done(error, user);
    });
  }
));

app.post('/auth/facebook/token',
  passport.authenticate('facebook-token'),
  function (req, res) {
    // do something with req.user
    res.send(req.user? 200 : 401);
  }
);

And it keeps telling me passport is undefined

so i added

var passport = require('passport');

Then using CocoaRestClient I called http://api.mydomain.com/auth/facebook/token (POST)
params : access_token : "Token i got from the android app"

and getting HTTP 401 Unauthorised, i need your help guys to know what i'am missing!

"InternalOAuthError: Failed to fetch user profile" thrown when access_token is invalid

I am using passport-facebook-token to authenticate users who use a RESTful API. When I use a valid access_token, everything works fine.

However, if I delete or replace a character in my access_token and then submit an API request, then I get the following error:

InternalOAuthError: Failed to fetch user profile

This causes the server to crash. Instead of this, I want to be able to choose what error message I send back to the client, and avoid crashing the server whenever someone sends me an invalid access_token.

Here is the code to reproduce the error:

"use strict"; // Enables ES6 features

// Import modules
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const passport = require('passport');
const FacebookTokenStrategy = require('passport-facebook-token');

// Constants
const PORT = process.env.PORT || 8080;

// Create app and add middleware
const app = express();
app.use(bodyParser.json());
app.use(passport.initialize());
// app.use(passport.session()); Should I use session??

// Implement (de)serializeUser methods -- Do I need this?
passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));

/*
 * Set up passport strategy
 */
passport.use('facebook-token', new FacebookTokenStrategy(
    {
    clientID        : process.env.FACEBOOK_APP_ID,
    clientSecret    : process.env.FACEBOOK_SECRET
  },
  (accessToken, refreshToken, profile, done) => {

    const user = {
        'firstName' : profile.name.givenName,
      'lastName'    : profile.name.familyName,
      'id'              : profile.id,
    }

    // Perform actions against User model here

    return done(null, user); // the user object we just made gets passed to the route's controller as `req.user`
  }
));

/*
 * User is logging in
 */
app.post(
    "/login",
    passport.authenticate('facebook-token'),
    (req, res) => {

        if (req.user) {
            res.json(req.user); // Return user object
        }
        else {
            res.status(400).json({"error": "Failed to authenticate user"}); // This is never called!
        }
    }
);

/*
 * Initialize app
 */
const server = app.listen(PORT, () => {
    const port = server.address().port;
    console.log("App now running on port", port);
});

Syntax for Sails for Facebook Authentication

I used the sails framework to authenticate a user with my custom facebook token strategy. It works perfectly. I copied this snippet of code from github to make it work, However, I don't quite understand the syntax of that last part which has (req, res); at the end. Obviously it's referring to request and response, but why is that line of code there, it seems to be in an awkward place. Authentication fails if I exclude that line of code. It must be important so I just need to figure out what it is doing .

    module.exports = {
   facebook: function(req, res) {  
   passport.authenticate('facebook-token', function(error, user, info) {
   res.ok();
   })
  (req, res); 
  }
     };

Handling token expiration

Hi!

Is module handling token expiration (e.g. user has changed facebook password) or is it my app's responsibility?

I'm asking because I saw this error in the app's logs:
InternalOAuthError: Failed to fetch user profile (status: 400 data: {"error":{"message":"Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.","type":"OAuthException","code":190,"error_subcode":460,"fbtrace_id":"XXXXXX"}})

OAuth2Strategy requires a authorizationURL option

Hello,

I need passport-facebook-token, for a mobile authentification.
I made a very simple code snippet to try it. But i got a error, when I execute it.

var facebookTokenStrategy = require('passport-facebook-token').Strategy;

app.use(passport.initialize());
app.use(passport.session());

passport.use(
    new facebookTokenStrategy(
        {
            clientID: '9008***',
            clientSecret: 'f8979***9',
            profileFields: ['id', 'email', 'displayName', 'photos']

        }, 
        function(accessToken, refreshToken, profile, done) {
            return done(null, {
                provider: 'facebook',
                id:'asdfSADFSDFsdfsdfsdfSDFSDFSDF',
                displayName:profile._json.name,
                name: {},
                emails: [
                    {value:profile._json.email, type:'home'}
                ],
                photos: []
            });
        }
    )
);

app.get('/', passport.authenticate('facebook-token'), function (req, res) {
     res.json({
        'message': 'Hello World'
    });
});

When I want la run the server I got this error :

TypeError: OAuth2Strategy requires a authorizationURL option

I looked on internet, I need to provide some env variables, so I also changed the to run the server :

BASE_URL="localhost:3000" FACEBOOK_KEY=93200 FACEBOOK_SECRET=f3217949 node app.js

Still having the same issue.
Thanks in advance for you helps. 👍

ps : If I can't find any solution with passport-facebook-token, can you give me some tips to accomplish a login/signup Facebook based only with the access token ?

InternalOAuthError: Failed to fetch user profile

Hi,

I'm getting this error when I tried to get the user profile from facebook

InternalOAuthError: Failed to fetch user profile
at /Users/jorgereyero/Workspace/xxxxx/node_modules/passport-facebook-token/lib/index.js:147:32
    at passBackControl (/Users/jorgereyero/Workspace/xxxxx/node_modules/passport-facebook-token/node_modules/passport-oauth/node_modules/passport-oauth2/node_modules/oauth/lib/oauth2.js:123:9)
    at IncomingMessage.<anonymous> (/Users/jorgereyero/Workspace/xxxxx/node_modules/passport-facebook-token/node_modules/passport-oauth/node_modules/passport-oauth2/node_modules/oauth/lib/oauth2.js:143:7)
    at IncomingMessage.emit (events.js:129:20)
    at _stream_readable.js:908:16
    at process._tickDomainCallback (node.js:381:11)

Thanks,

Jorge.

Inconsistent Unauthorized Error

I am obtaining an accessToken via the javascript SDK, and sending it to passport for authorization and subsequently logging in / creating an account based on my own logic. This works about ~50% of the time, but the other half of the time it fails before reaching the passport callback or the route handler function - I get a 401 Unauthorized error.

On the client-side (Angular):


            var fbJson = {
                access_token: data.authResponse.accessToken
            };

            $http.post(Global.apiUrl + 'users/facebook/login', fbJson).
            success(function(data, status, headers, config) {
                successCallback(data);
            }).
            error(function(data, status, headers, config) {
                errorCallback(data);
            });

For the passport configuration:

passport.use(new FacebookTokenStrategy({
            clientID: config.facebook.clientID,
            clientSecret: config.facebook.clientSecret,
        }, function(accessToken, refreshToken, profile, done) {
            // Fails before getting to the callback for handling user lookup and/or creation
        })
    );

In passport-facebook-token/lib/strategy.js, I did a console.log of where I guessed the error was occurring:

FacebookTokenStrategy.prototype.userProfile = function(accessToken, done) {
  ....
  this._oauth2.getProtectedResource(url, accessToken, function (err, body, res) {
    if (err) { 
      console.log('FacebookTokenStrategy.prototype.userProfile InternalOAuthError failed to fetch user profile', err);
      return done(new InternalOAuthError('failed to fetch user profile', err)); 
    }
   ....
  });
};

...which gives me the error:

FacebookTokenStrategy.prototype.userProfile InternalOAuthError failed to fetch user profile { [Error: connect ECONNREFUSED]
  code: 'ECONNREFUSED',
  errno: 'ECONNREFUSED',
  syscall: 'connect' }

Any ideas on what's going on? As I mentioned, this only happens about half the time.

"Error: Failed to serialize user into session" even when not using passport.session() middleware

I am using passport-facebook-token to authenticate users who use a RESTful API. At the moment I want to authenticate users every time they make an API call, and so I did not add the passport.session() middleware.

However, every time I try to authenticate I get the following error:

Error: Failed to serialize user into session

When I add the following code, everything starts working as normal:

passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));

Why is this happening even though I am specifically NOT using the passport.session() middleware? Why do I need to call serializeUser & deserializeUser when there is no session recorded?

Here is all the code to reproduce the error:

"use strict"; // Enables ES6 features

// Import modules
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const passport = require('passport');
const FacebookTokenStrategy = require('passport-facebook-token');

// Constants
const PORT = process.env.PORT || 8080;

// Create app and add middleware
const app = express();
app.use(bodyParser.json());
app.use(passport.initialize());
// app.use(passport.session()); Should I use session??

// Implement (de)serializeUser methods -- Do I need this?
// passport.serializeUser((user, done) => done(null, user));
// passport.deserializeUser((user, done) => done(null, user));

/*
 * Set up passport strategy
 */
passport.use('facebook-token', new FacebookTokenStrategy(
    {
    clientID        : process.env.FACEBOOK_APP_ID,
    clientSecret    : process.env.FACEBOOK_SECRET
  },
  (accessToken, refreshToken, profile, done) => {

    const user = {
        'firstName' : profile.name.givenName,
      'lastName'    : profile.name.familyName,
      'id'              : profile.id,
    }

    // Perform actions against User model here

    return done(null, user); // the user object we just made gets passed to the route's controller as `req.user`
  }
));

/*
 * User is logging in
 */
app.post(
    "/login",
    passport.authenticate('facebook-token'),
    (err, req, res) => {

        if (req.user) {
            res.json(req.user); // Return user object
        }
        else {
            res.status(400).json({"error": "Failed to authenticate user"}); // This is never called!
        }
    }
);

/*
 * Initialize app
 */
const server = app.listen(PORT, () => {
    const port = server.address().port;
    console.log("App now running on port", port);
});


facebook gender is empty for Sails framework?

console.log of profile gives :

     id: '336360503408940',
  displayName: 'Ray Slim',
 name: { familyName: 'Slim', givenName: 'Ray', middleName: '' },
 gender: '',
  emails: [ { value: '' } ],
 photos: [ { value: 'https://graph.facebook.com/v2.6/336360503408940/picture?type=large' } ],
 _raw: '{"id":"336360503408940","name":"Ray Slim","last_name":"Slim","first_name":"Ray"}',
 _json: 
  { id: '336360503408940',
   name: 'Ray ',
     last_name: 'Ray Slim',

As you can see, gender has no value. Why is that? Below is my token strategy, similar to a lot of them

var facebookLoginStrategy = new FacebookTokenStrategy({
clientID: '1512072982155691',
clientSecret: '7b89b4bdfba3408b68efe9fd1c3a8164'
}, function(accessToken, refreshToken, profile, done) {

User.findOrCreate({ id: profile.id}, function (err, user) {

console.log(profile)

return done(err, user);

});

});

Long-lived Facebook Token

Will there be any support for returning a long-lived Facebook Token as well? Or even a helper function that can be used to retrieve one from FB?

Error after update to new version

Hi,

after update the new version I'm getting the next error:

usermng/node_modules/passport-facebook-token/node_modules/passport-oauth/node_modules/passport-oauth2/lib/strategy.js:81
  if (!options.authorizationURL) { throw new TypeError('OAuth2Strategy require
                                         ^
TypeError: OAuth2Strategy requires a authorizationURL option
    at new OAuth2Strategy (usermng/node_modules/passport-facebook-token/node_modules/passport-oauth/node_modules/passport-oauth2/lib/strategy.js:81:42)

My verify function looks like this:

passport.use(new FacebookTokenStrategy({
    clientID: 'xxxxxxxxxxxxxx',
    clientSecret: 'xxxxxxxxxxxxx'
  },
  function(accessToken, refreshToken, profile, done) {
      console.dir(profile);
      return done(null, {username: profile.emails[0].value, id:profile.id, name:profile.name});
  }
));

Thanks,

Jorge

Readme

Hi,
This node module is working well. However, it's hard to figure out from the Readme what it's really useful for, how it's different from passport-facebook, and in which use cases we might prefer using passport-facebook-token. I finally use it in combination with client-side facebook login, and this should be explained better in the readme. Thank you again for this project it was really useful.

using two different app ids

We are using a single server instance for two different facebook app ids used on our javascript client (one with our domain name and one with localhost as the site url in the facebook developers console).

Is there a way to have the clientID and clientSecret set per request rather than when the service starts?

Graph API v2.0 is deprecated

I have received this morning a notice from FB that my application is still using methods from v2.0 which will be deprecated on Aug 8th. I may be now barking at the wrong tree, but shouldn't calls to https://graph.facebook.com/oauth/access_token be versioned as well (like https://graph.facebook.com/v2.4/me)?

Provisional headers are shown issue

Provisional headers are shown
authorization:Bearer RUFBRlJZd29jZVJFQkFBWkNFb1pBdWVkeFFxeHZYc042WkNaQWVNUmNMODdNWkJ2SVJMWGxmbmpaQmJpTW9mV3REVktLeE1HakIzaUZpU2JhUGVqWkJEVk04QWN4OWNwd2lhazd5ajhmNUpsNGY0ZGpVem1teU1rMTRkNXk5aFF5MVpBTXg1Q3pqc3F2aHZtRmVqdFpDVTJlRmtDUXdUVmd5TG5RZUlDRUdLMWZrM2daRFpE
content-type:application/json
Origin:http://localhost:4200
Referer:http://localhost:4200/Login
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36

Dynamic Client ID/Secret

I need to use a dynamic client id/secret, depending on the request i'll need to use differents credentials.
Because in the post req i have passport.authenticate('facebook-token') and the strategy where i put the credentials is inside another script config/passport.js.
Do you have any idea how can i do that?
Thanks

access_token from header is no longer supported

Hello!
I haven't find any reason why it was removed after 2.3.0.
currently:

var accessToken = req.body && req.body[this._accessTokenField] || req.query && req.query[this._accessTokenField];

2.3.0:

var accessToken = (req.body && req.body[self._accessTokenField]) || (req.query && req.query[self._accessTokenField]) || (req.headers && req.headers[self._accessTokenField]);

Can you tell me what was the reason behind it? I was using headers in my project.

Thanks!

Unauthorized error

Hi,

I am trying to use this module so in future I get the access_token from mobile devices(whether from native library or third-party SDK) and authenticate/authorize users.

For test, I am using passport-facebook for my browser-based app and it works perfectly. It brings back a token, is this the access token this module needs? Because I used all sort of access_token and I always get Unauthorized 401 error.

Please guide me to use this module as it's necessary for people who are developing mobile apps and have their backends on NodeJS+PassportJS. A simple example of getting access_token and a sample post URL with JSON would mean a lot.

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.