All Projects → eggjs → Egg Passport

eggjs / Egg Passport

Licence: mit
passport plugin for egg

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Egg Passport

Egg Sequelize
Sequelize for Egg.js
Stars: ✭ 540 (+451.02%)
Mutual labels:  egg, egg-plugin
Egg Cancan
cancancan like authorization plugin for Egg.js
Stars: ✭ 47 (-52.04%)
Mutual labels:  egg, egg-plugin
egg-rest
Restful API plugin for egg
Stars: ✭ 106 (+8.16%)
Mutual labels:  egg, egg-plugin
Egg View React Ssr
Egg React Server Side Render (SSR) Plugin
Stars: ✭ 55 (-43.88%)
Mutual labels:  egg, egg-plugin
Egg Mongoose
Stars: ✭ 386 (+293.88%)
Mutual labels:  egg, egg-plugin
egg-view-vue-ssr
Egg Vue Server Side Render (SSR) Plugin
Stars: ✭ 90 (-8.16%)
Mutual labels:  egg, egg-plugin
Egg Restfulapi
🏅 基于Egg.js 2.0 & {mongoose,jwt}RESTful API 模板,用于快速集成开发RESTful前后端分离的服务端。
Stars: ✭ 524 (+434.69%)
Mutual labels:  egg, egg-plugin
egg-swagger
swagger-ui plugin for egg ,Demo:
Stars: ✭ 26 (-73.47%)
Mutual labels:  egg, egg-plugin
Egg View
Stars: ✭ 35 (-64.29%)
Mutual labels:  egg, egg-plugin
Egg Graphql
Stars: ✭ 345 (+252.04%)
Mutual labels:  egg, egg-plugin
Egg Valid
👮Validation plugin for eggjs
Stars: ✭ 10 (-89.8%)
Mutual labels:  egg, egg-plugin
Egg Authz
egg-authz is an authorization middleware for Egg.js based on Casbin
Stars: ✭ 50 (-48.98%)
Mutual labels:  egg, egg-plugin
egg-y-validator
☯️ Egg Magic Validator (Egg 魔法验证工具)
Stars: ✭ 30 (-69.39%)
Mutual labels:  egg, egg-plugin
Egg View Ejs
egg view plugin for ejs.
Stars: ✭ 54 (-44.9%)
Mutual labels:  egg, egg-plugin
egg-userservice
userservice plugin for egg
Stars: ✭ 21 (-78.57%)
Mutual labels:  egg, egg-plugin
egg-session
session plugin for egg
Stars: ✭ 48 (-51.02%)
Mutual labels:  egg, egg-plugin
egg-oracle
OracleDB plugin for egg
Stars: ✭ 23 (-76.53%)
Mutual labels:  egg, egg-plugin
egg-parameters
Merge all parameters (ctx.params, ctx.request.query, ctx.request.body) into ctx.params like Rails application.
Stars: ✭ 24 (-75.51%)
Mutual labels:  egg, egg-plugin
Egg Mysql
MySQL plugin for egg
Stars: ✭ 276 (+181.63%)
Mutual labels:  egg, egg-plugin
Egg 24time
A Twitter-like news and social server for Egg. 微信小程序社区全栈解决方案
Stars: ✭ 493 (+403.06%)
Mutual labels:  egg, egg-plugin

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].