passport icon indicating copy to clipboard operation
passport copied to clipboard

Using PassportJS to manually authenticate a username/password

Open jhyland87 opened this issue 8 years ago • 10 comments

Im trying to use PassportJS as a means of authentication for an application I'm writing. The application itself is more of a CLI tool, which doesn't use express.

I was trying to find a way to use PassportJS to authenticate a username/password manually, but in the examples inside the documentation, you're actually using ExpressJS and setting Passport as the authentication schema.

Is there any documentation on just how to take a username/password, authenticate, and execute a callback or preferably return a promise?

jhyland87 avatar Jan 14 '16 17:01 jhyland87

A stand alone version of passport would doors to so many more use cases, i'm trying to adapt it to graphql api and struggling at the moment

du5rte avatar Apr 15 '16 18:04 du5rte

@monteirocode same here. were you successful as of now or did you use different modules?

codepunkt avatar Jun 18 '16 15:06 codepunkt

@gonsfx I concluded it's better doing it manually, once you get your head around oauth2 it's actually quite easy to do, the APIs are simple and well documented, using passport just adds confusion. I'm drafting a human non-programmer understandable documentation of oauth you can twit me you want me to have a look at it.

du5rte avatar Jun 18 '16 16:06 du5rte

Here's an example of manually signing up and logging in a user. Yep, it looks nasty:

function signup({ email, password, req }) {
  const user = new User({ email, password });

  return User.findOne({ email })
    .then(existingUser => {
      if (existingUser) { throw new Error('Email in use'); }
      return user.save();
    })
    .then(user => {
      return new Promise((resolve, reject) => {
        req.logIn(user, (err) => {
          if (err) { reject(err); }
          resolve(user);
        });
      });
    });
}
function login({ email, password, req }) {
  return new Promise((resolve, reject) => {
    passport.authenticate('local', (err, user) => {
      if (err) { reject(err); }
      if (!user) { reject('Invalid credentials.'); }

      req.login(user, () => resolve(user));
    })({ body: { email, password } });
  });
}

I'm making user of GraphQL as well, which expects a promise, not a callback.

StephenGrider avatar Feb 07 '17 22:02 StephenGrider

Great solution @StephenGrider. I too am using GraphQL with Password, and I'm amazed at how difficult it is!

A simple passport.authenticateWithCredentials method that's completely divorced from the HTTP layer should be almost trivial to add:

function login({ email, password }) {
  return passport.authenticateWithCredentials('local', { email, password })
    .then(user => doSomethingWithSuccessfullyLogedInUser(user))
    .catch(err => handleALoginError(err);
};

Does the Passport team object philosophically to a method like this, or is it simply an issue of "no one has submitted a PR yet"?

machineghost avatar Jan 30 '18 18:01 machineghost

Yes @machineghost, seems @jaredhanson doesn't like promises at all. See https://github.com/jaredhanson/passport/issues/536.

sheerlox avatar Apr 25 '18 16:04 sheerlox

So, is passport meant to be exclusively used for express or connect ? I'm also trying to use it to authenticate users to my GraphQL API, but it's been quite hard.

ManifoldFR avatar May 06 '18 00:05 ManifoldFR

I asked about this on Stack Overflow and someone there posted a solution. A basic Passport function would be more ideal, but in the meantime this solution works, so hopefully it helps some people:

https://stackoverflow.com/questions/47899786/how-can-i-authenticate-a-graphql-endpoint-with-passport

machineghost avatar May 06 '18 01:05 machineghost

+1 for having this feature. It would be very useful for use-cases such as authentication in GraphQL context as other commentors have mentioned.

tumainimosha avatar Nov 05 '20 15:11 tumainimosha

I would also like to echo my desire for a feature like this. My use case is:

Using Express and PassportJS to authenticate users. Using the accessToken from login to perform API functions with that same provider. I have one main account for each provider that controls API interactions for all non-authed users. Authed users also need to be able to control API interactions, when authed user is present, on the same routes.

I am doing this across multiple subdomains on the same host, so what I am trying to accomplish is a bit more complicated than described, but... a way to attach a single user to a passport strategy or be able to manually log a user in with their credentials using PassportJS, where my application looks to when it determines whether or not a user has access to a resource, would be really useful.

There are so many articles online that say you don't need PassportJS to do anything and that it's making oauth more difficult, yet a lot of us are out there trying to use it anyway. Maybe this would help bridge that gap?

KenEucker avatar Dec 21 '20 17:12 KenEucker