Home

Awesome

微信小程序 Authentication for Feathers

Travis (.org) branch npm bundle size npm version Known Vulnerabilities NPM license

Install

npm i @feathers-weapp/auth

Usage

Step1: update feathers configuration

add new authentication strategy into feathers default configuration json file.

// config/default.json
"authentication": {
  "authStrategies": [
    // ...
    "weapp" // strategy name, such as wxauth, whatever
  ],
  // ...
  "weapp": { // keep identic with strategy name
    "appId": "WX_APP_ID",
    "appSecret": "WX_APP_SECRET"
  }
},

Step2: setup auth strategy in authentication service

Implements the entityResolver protocol and register new auth-strategy.

// authentication.js
const WeappStrategy = require('@feathers-weapp/auth')

// declare a function to find, patch or create authentication entity(eg: users)
const entityResolverBuilder = (strategy) => {
  const {configuration:{key, secret}, entityService:service} = strategy
  const decrypt = WeappStrategy.decipherer(key, secret)

  return {
    // to decrypt encrypted data which post from clients
    async decryptData(rawData, params) {
      return await decrypt(rawData)
    },
    
    // to find an entity with specified auth-data
    async findEntity(authData, params) {
      const [entity] = await service.find({query: {openId: authData.openId, $limit: 1}, paginate: false})
      return entity
    },
    
    // optional, to update an entity with specified auth-data
    async patchEntity(entity, authData, params) {
      return await service.path(entity.id, {userInfo: authData.userInfo})
    },

    // to create an entity when not found
    async createEntity(authData, params) {
      return await service.create({openId: authData.openId, userInfo: authData.userInfo})
    }
  }
}

module.exports = function configureAuthenticationService(app) {
  const authentication = new AuthenticationService(app);
  // ... skipped
  authentication.register('weapp', new WeappStrategy(entityResolverBuilder));
  // ... skipped
}
// client
const app = feathers()
app.service('authentication').create({
  strategy: 'weapp', 
  code: 'login code',
  rawData: '',
  signature: '',
  encryptedData: '',
  iv: ''
}).then(({accessToken}) => console.log('JWT token', accessToken))

API

rawData object

interface rawData {
  code: string;
  rawData: string;
  signature: string;
  encryptedData: string;
  iv: string
}

authData object

interface authData {
  openId: string;
  sessionKey: string;
  userInfo: userInfo
}

userInfo object

interface userInfo {
  nickname: string;
  gender: number;
  language: string;
  city: string;
  province: string;
  country: string;
  avatarUrl: string;
  unionId?: string;
  watermark: any
}

entityResolver object

interface entityResolver {
  decryptData(rawData: rawData, params: object): object;
  findEntity(authData: authData, params: object): Entity | null;
  [patchEntity(entity: Entity, authData: authData, params: object)]: Entity;
  createEntity(entity: object, authData: authData, params: object): Entity;
}

entityResolverBuilder function

function entityResolverBuilder(strategy:WeappStrategy):entityResolver

WeappStrategy class

class WeappStrategy {
  constructor(builder:entityResolverBuilder);
  app:Application;
  name:string;
  authentication:AuthenticationBase;
  configuration:object;
  entityService:Service;
}