OAuth1 身份验证

npm version Changelog

$ npm install @feathersjs/authentication-oauth1 --save

@feathersjs/authentication-oauth1 is a server side module that allows you to use any Passport OAuth1 authentication strategy within your Feathers application, most notably Twitter.

This module contains 2 core pieces:

  1. The main initialization function

  2. The Verifier class

Configuration

In most cases initializing the module is as simple as doing this:

const feathers = require('@feathersjs/feathers');
const authentication = require('@feathersjs/authentication');
const jwt = require('@feathersjs/authentication-jwt');
const oauth1 = require('@feathersjs/authentication-oauth1');

const session = require('express-session');
const TwitterStrategy = require('passport-twitter').Strategy;
const app = feathers();

// Setup in memory session
app.use(session({
  secret: 'super secret',
  resave: true,
  saveUninitialized: true
}));

// Setup authentication
app.configure(authentication(settings));
app.configure(jwt());
app.configure(oauth1({
  name: 'twitter',
  Strategy: TwitterStrategy,
  consumerKey: '<your consumer key>',
  consumerSecret: '<your consumer secret>'
}));

// Setup a hook to only allow valid JWTs to authenticate
// and get new JWT access tokens
app.service('authentication').hooks({
  before: {
    create: [
      authentication.hooks.authenticate(['jwt'])
    ]
  }
});

这将从配置文件中的全局身份验证对象中提取.它还将混合以下默认值, 可以自定义.

注册OAuth1插件将自动设置路由以处理OAuth重定向和授权.

Options

{
    idField: '<provider>Id', // The field to look up the entity by when logging in with the provider. Defaults to '<provider>Id' (ie. 'twitterId').
    path: '/auth/<provider>', // The route to register the middleware
    callbackURL: 'http(s)://hostame[:port]/auth/<provider>/callback', // The callback url. Will automatically take into account your host and port and whether you are in production based on your app environment to construct the url. (ie. in development http://localhost:3030/auth/twitter/callback)
    entity: 'user', // the entity that you are looking up
    service: 'users', // the service to look up the entity
    passReqToCallback: true, // whether the request object should be passed to `verify`
    session: true, // whether to use sessions,
    handler: function, // Express middleware for handling the oauth callback. Defaults to the built in middleware.
    formatter: function, // The response formatter. Defaults the the built in feathers-rest formatter, which returns JSON.
    Verifier: Verifier, // A Verifier class. Defaults to the built-in one but can be a custom one. See below for details.
    makeQuery: function // Makes query for finding an existing user. Defaults to (profile, options) => ({ [options.idField]: profile.id })
}

Additional passport strategy options can be provided based on the OAuth1 strategy you are configuring.

Verifier

这是验证类, 它通过在给定服务上查找实体(通常是“用户”)来处理OAuth1验证, 并创建或更新实体并返回它们.它具有以下可以覆盖的方法.除了``verify``之外, 所有方法都返回一个promise, 它与`passport-oauth1 <https://github.com/jaredhanson/passport-oauth1>`_具有完全相同的签名.

{
    constructor(app, options) // the class constructor
    _updateEntity(entity) // updates an existing entity
    _createEntity(entity) // creates an entity if they didn't exist already
    _normalizeResult(result) // normalizes result from service to account for pagination
    verify(req, accessToken, refreshToken, profile, done) // queries the service and calls the other internal functions.
}

可以扩展 Verifier 类, 以便您可以自定义它的行为, 而无需重写和测试完全自定义的本地Passport实现.虽然如果您不想使用此插件, 这始终是一个选项.

An example of customizing the Verifier:

import oauth1, { Verifier } from '@feathersjs/authentication-oauth1';

class CustomVerifier extends Verifier {
  // The verify function has the exact same inputs and
  // return values as a vanilla passport strategy
  verify(req, accessToken, refreshToken, profile, done) {
    // do your custom stuff. You can call internal Verifier methods
    // and reference this.app and this.options. This method must be implemented.

    // the 'user' variable can be any truthy value
    // the 'payload' is the payload for the JWT access token that is generated after successful authentication
    done(null, user, payload);
  }
}

app.configure(oauth1({
  name: 'twitter'
  Strategy: TwitterStrategy,
  consumerKey: '<your consumer key>',
  consumerSecret: '<your consumer secret>',
  Verifier: CustomVerifier
}));

Customizing The OAuth Response

每当您使用Twitter等OAuth1提供程序进行身份验证时, 提供程序都会发送回一个``accessToken``, refreshToken``和一个``profile, 其中包含基于OAuth1``范围`的经过身份验证的实体的信息.你已经要求并获得批准.“

每当您使用OAuth1提供程序(如Twitter)进行身份验证时, 提供程序将发回一个 accessToken, refreshToken 和一个包含基于OAuth1`` scope的身份的 profile 的信息.验证实体.您已申请并获得批准. “

app.configure(oauth1({
  name: 'twitter',
  entity: 'user',
  service: 'users',
  Strategy,
  consumerKey: '<your consumer key>',
  consumerSecret: '<your consumer secret>'
}));

function customizeTwitterProfile() {
  return function(context) {
    console.log('Customizing Twitter Profile');
    // If there is a twitter field they signed up or
    // signed in with twitter so let's pull the email. If
    if (context.data.twitter) {
      context.data.email = context.data.twitter.email;
    }

    // If you want to do something whenever any OAuth
    // provider authentication occurs you can do this.
    if (context.params.oauth) {
      // do something for all OAuth providers
    }

    if (context.params.oauth.provider === 'twitter') {
      // do something specific to the twitter provider
    }

    return Promise.resolve(context);
  };
}


app.service('users').hooks({
  before: {
    create: [customizeTwitterProfile()],
    update: [customizeTwitterProfile()]
  }
});

Client Usage

当该模块是注册服务器端时, 无论您是否使用 feathers-authentication-client, 用户都必须导航到身份验证策略URL.这可以通过设置``window.location``或通过应用程序中的链接来实现.

例如, 您可能有Twitter的登录按钮:

<a href="/auth/twitter" class="button">Login With Twitter</a>