Coder Social home page Coder Social logo

egg-passport's Introduction

egg-passport

NPM version build status Test coverage David deps Known Vulnerabilities npm download

passport plugin for egg, base on passportjs.

Install

$ npm i egg-passport

Usage

enable passport plugin

// config/plugin.js
exports.passport = {
  enable: true,
  package: 'egg-passport',
};

Using Github and Twitter strategy

// config/config.default.js
exports.passportGithub = {
  key: 'my oauth2 clientID',
  secret: 'my oauth2 clientSecret',
};

exports.passportTwitter = {
  key: 'my oauth1 consumerKey',
  secret: 'my oauth1 consumerSecret',
};

Authenticate Requests

Use app.passport.mount(strategy[, options]), specifying the 'github' and 'twitter' strategy, to authenticate requests.

// app/router.js
module.exports = app => {
  app.get('/', 'home.index');

  // authenticates routers
  app.passport.mount('github');
  // this is a passport router helper, it's equal to the below codes
  //
  // const github = app.passport.authenticate('github');
  // app.get('/passport/github', github);
  // app.get('/passport/github/callback', github);

  // custom options.login url and options.successRedirect
  app.passport.mount('twitter', {
    loginURL: '/account/twitter',
    // auth success redirect to /
    successRedirect: '/',
  });
};

Verify and store user

Use app.passport.verify(async (ctx, user) => {}) hook:

// app.js
module.exports = app => {
  app.passport.verify(async (ctx, user) => {
    // check user
    assert(user.provider, 'user.provider should exists');
    assert(user.id, 'user.id should exists');

    // find user from database
    //
    // Authorization Table
    // column   | desc
    // ---      | --
    // provider | provider name, like github, twitter, facebook, weibo and so on
    // uid      | provider unique id
    // user_id  | current application user id
    const auth = await ctx.model.Authorization.findOne({
      uid: user.id,
      provider: user.provider,
    });
    const existsUser = await ctx.model.User.findOne({ id: auth.user_id });
    if (existsUser) {
      return existsUser;
    }
    // call user service to register a new user
    const newUser = await ctx.service.user.register(user);
    return newUser;
  });
};

How to develop an egg-passport-${provider} plugin

See example: egg-passport-twitter.

  • Plugin dependencies on egg-passport to use app.passport APIs.
// package.json
{
  "eggPlugin": {
    "name": "passportTwitter",
    "dependencies": [
      "passport"
    ]
  },
}
  • Define config and set default values

Must use key and secret instead of consumerKey|clientID and consumerSecret|clientSecret.

// config/config.default.js
exports.passportTwitter: {
  key: '',
  secret: '',
  callbackURL: '/passport/twitter/callback',
};
  • Init Strategy in app.js and format user in verify callback
// app.js
const debug = require('debug')('egg-passport-twitter');
const assert = require('assert');
const Strategy = require('passport-twitter').Strategy;

module.exports = app => {
  const config = app.config.passportTwitter;
  // must set passReqToCallback to true
  config.passReqToCallback = true;
  assert(config.key, '[egg-passport-twitter] config.passportTwitter.key required');
  assert(config.secret, '[egg-passport-twitter] config.passportTwitter.secret required');
  // convert to consumerKey and consumerSecret
  config.consumerKey = config.key;
  config.consumerSecret = config.secret;

  // register twitter strategy into `app.passport`
  // must require `req` params
  app.passport.use('twitter', new Strategy(config, (req, token, tokenSecret, params, profile, done) => {
    // format user
    const user = {
      provider: 'twitter',
      id: profile.id,
      name: profile.username,
      displayName: profile.displayName,
      photo: profile.photos && profile.photos[0] && profile.photos[0].value,
      token,
      tokenSecret,
      params,
      profile,
    };
    debug('%s %s get user: %j', req.method, req.url, user);
    // let passport do verify and call verify hook
    app.passport.doVerify(req, user, done);
  }));
};
  • That's all!

APIs

extent application

  • app.passport.mount(strategy, options): Mount the login and the login callback routers to use the given strategy.
  • app.passport.authenticate(strategy, options): Create a middleware that will authorize a third-party account using the given strategy name, with optional options.
  • app.passport.verify(handler): Verify authenticated user
  • app.passport.serializeUser(handler): Serialize user before store into session
  • app.passport.deserializeUser(handler): Deserialize user after restore from session

extend context

  • ctx.user: get the current authenticated user
  • ctx.isAuthenticated(): Test if request is authenticated
  • * ctx.login(user[, options]): Initiate a login session for user.
  • ctx.logout(): Terminate an existing login session

Unit Tests

This plugin has includes some mock methods to helper you writing unit tests more conveniently.

app.mockUser([user]): Mock an authenticated user

const mm = require('egg-mock');

describe('mock user demo', () => {
  let app;
  before(() => {
    app = mm.app();
    return app.ready();
  });
  after(() => app.close());

  afterEach(mm.restore);

  it('should show authenticated user info', () => {
    app.mockUser();
    return request(app.callback())
      .get('/')
      .expect(/user name: mock_name/)
      .expect(200);
  });
});

app.mockUserContext([user]): Mock a context instance with authenticated user

it('should get authenticated user and call service', async () => {
  const ctx = app.mockUserContext();
  const result = await ctx.service.findUser({ id: ctx.user.id });
  assert(result.user.id === ctx.user.id);
});

Questions & Suggestions

Please open an issue here.

License

MIT

egg-passport's People

Contributors

atian25 avatar dead-horse avatar fengmk2 avatar jeff-tian avatar lgtm-com[bot] avatar lightrabbit avatar thonatos avatar vagusx avatar whxaxes avatar zewei94yomi 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

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.