Coder Social home page Coder Social logo

azard / egg-oauth2-server Goto Github PK

View Code? Open in Web Editor NEW
180.0 180.0 45.0 44 KB

:star2: OAuth2 server plugin for egg.js based on node-oauth2-server

License: MIT License

JavaScript 100.00%
egg egg-plugin eggjs node node-oauth2-server nodejs npm-package oauth2 oauth2-server

egg-oauth2-server's People

Contributors

azard avatar dead-horse avatar ithinco avatar mingyuan-xia avatar ole3021 avatar senique avatar shyser avatar sm2017 avatar thonatos avatar zemzheng 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

egg-oauth2-server's Issues

accessTokenLifetime 不支持无限期

config

config.oAuth2Server = {
    debug: appInfo.env === 'local',
    grants: ['password'],
    accessTokenLifetime: null,
    refreshTokenLifetime: null
}

Error

 nodejs.invalid_argument: Missing parameter: `accessTokenLifetime`
    at new InvalidArgumentError (/Volumes/Mac/Projects/Node/liubangback/node_modules/oauth2-server/lib/errors/invalid-argument-error.js:21:14)
    at new TokenHandler (/Volumes/Mac/Projects/Node/liubangback/node_modules/oauth2-server/lib/handlers/token-handler.js:43:11)
    at OAuth2Server.token (/Volumes/Mac/Projects/Node/liubangback/node_modules/oauth2-server/lib/server.js:74:10)
    at Object.<anonymous> (/Volumes/Mac/Projects/Node/liubangback/node_modules/egg-oauth2-server/lib/server.js:82:36)
    at Generator.next (<anonymous>)
    at Object.dispatch (/Volumes/Mac/Projects/Node/liubangback/node_modules/koa-router/lib/router.js:334:5)
    at dispatch.next (<anonymous>)
    at onFulfilled (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:65:19)
    at /Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:54:5
    at new Promise (<anonymous>)
    at Object.co (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:50:10)
    at Object.toPromise (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:118:63)
    at next (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:99:29)
    at onFulfilled (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:69:7)
    at /Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:54:5
    at new Promise (<anonymous>)
    at Object.co (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:50:10)
    at Object.toPromise (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:118:63)
    at next (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:99:29)
    at onFulfilled (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:69:7)
    at /Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:54:5
    at new Promise (<anonymous>)
    at Object.co (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:50:10)
    at Object.toPromise (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:118:63)
    at next (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:99:29)
    at onFulfilled (/Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:69:7)
    at /Volumes/Mac/Projects/Node/liubangback/node_modules/co/index.js:54:5
    at new Promise (<anonymous>)

lib下的server.js有错

原来代码如下:
   const user = yield server.options.model.getUser(
                username,
                password,
      );
password后面多了个逗号

Saving context in application is an anti-pattern

I found on some occasions, the Model being instantiated with the last request context, then I found this:

this.ctx = ctx;

You should never save ctx in application ever. This is my fix:

{
  getServer(ctx) {
    if (!ctx[SERVER]) {
      const { config, model: Model } = this;
      const model = new Model(ctx);
      ctx[SERVER] = new AuthServer(Object.assign(config, { model }));
      return ctx[SERVER];
    }
    return ctx[SERVER];
  }
}

status code must be a number

018-07-29 15:50:49,771 ERROR 84272 [-/::1/-/8ms GET /user/token] nodejs.AssertionError [ERR_ASSERTION]: status code must be a number

关于revokeToken/Logout的实现

在文档说明中有revoceToken的实现,但是再实例的抽象中没有logout之类的方法,是不是缺少了关于logout的实现?还是有别的什么用法?

OAuth2.0授权服务验证失败

2017-09-21 6 03 25

fetch('http://127.0.0.1:7001/user/token',{method: 'POST', mode:'cors',credentials: 'include',headers:{"Content-Type":"application/x-www-form-urlencoded",Authorization: 'Basic bXlfYXBwOm15X3NlY3JldA=='},body:'username=egg-oauth2-server&password=azard&grant_type=password'}) .then(function(res){return res.json()}).then(function(res){console.log(res)})

下面的Authorization是上一个接口的token_type + access_token ;

fetch('http://127.0.0.1:7001/user/authenticate',{method: 'GET', mode:'cors',credentials: 'include',headers:{Authorization: 'Bearer 51375d61bc4f4f7e9661d9a71f0745441024ee7c'}}) .then(function(res){return res.json()}).then(function(res){console.log(res)})

返回错误

{"error":"server_error","error_description":"Server error: `accessTokenExpiresAt` must be a Date instance"}

好像是格式有问题

获取token老是报错

获取token body里面传哪些参数呢,希望文档可以写下
{
"error": "invalid_client",
"error_description": "Invalid client: cannot retrieve client credentials"
}

Missing parameter: `grant_type`

I have try egg-auth2-server as shown in test.
But I got the error message : "Missing parameter: grant_type" with my request as follows:

request(${host}/user/token, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', Authorization: 'Basic bXlfYXBwOm15X3NlY3JldA==', }, data: { grant_type: 'password', username: 'egg-oauth2-server', password: 'azard', }, });

'oauth.js' and 'config.default.js' are the same as shown in test dir.
Wish to get some help, thanks.

Issue with eggjs 2.0

在 egg.js 中使用在获取token的saveToken之后会报如下错误

egg: 2.0.0 
node: 8.9.0
os: mac 10.13.1
2017-11-29 03:22:00,577 ERROR 58549 [-/::1/-/126ms POST /login] nodejs.TypeError: undefined is not a function
    at Object.<anonymous> (/Users/ole3021/ducklab/ci-backend/node_modules/egg-oauth2-server/lib/server.js:102:20)
    at Generator.next (<anonymous>)
    at onFulfilled (/Users/ole3021/ducklab/ci-backend/node_modules/co/index.js:65:19)
    at <anonymous>

经初步排查错误代码发生在lib/server.js中第101行的if (token) { yield* next; }, 其中next不是可yield的generator函数,而是ctx对象。

修正方法可使用if(token) ctx.body = token 来替代(初步解决方法)

问题应该是对egg新版本的适配问题, 刚刚发现, 有时间的话会提pr,另外希望可以尽快适配并做好测试。:)

support app/extend/oauth.ts

both

  • app/extend/oauth.ts
  • app/extend/oauth.js

should be acceptable

是否可以考虑允许使用 app/extend/oauth.ts。
当我的项目是用 ts 来编写的时候 dev/debug 比较方便点。

options.headers.hasOwnProperty is not a function

2017-09-21 16:37:56,696 ERROR 32793 [-/127.0.0.1/-/10737ms GET /user/token] nodejs.TypeError: options.headers.hasOwnProperty is not a function
at new Response (/Users/tusm/github/mygithub/egg-cms/node_modules/oauth2-server/lib/response.js:16:25)
at Object. (/Users/tusm/github/mygithub/egg-cms/node_modules/egg-oauth2-server/lib/server.js:63:24)
at Generator.next ()
at Object.dispatch (/Users/tusm/github/mygithub/egg-cms/node_modules/koa-router/lib/router.js:334:12)
at dispatch.next ()
at onFulfilled (/Users/tusm/github/mygithub/egg-cms/node_modules/co/index.js:65:19)
at /Users/tusm/github/mygithub/egg-cms/node_modules/co/index.js:54:5
at Promise ()
at Object.co (/Users/tusm/github/mygithub/egg-cms/node_modules/co/index.js:50:10)

// Store the headers in lower case.
  for (var field in options.headers) {
    if (options.headers.hasOwnProperty(field)) {
      this.headers[field.toLowerCase()] = options.headers[field];
    }
  }

‌‌typeof this.ctx.response.headers
‌object
‌‌typeof this.ctx.response.proto
‌object
‌‌typeof this.ctx.response.headers.proto
‌undefined
tips: egg issues

关于 model 的讨论

目前的设计方式

  • 用户在 app/extend/oauth.js 中提供策略
  • 插件会在 app.js 中调用 loadFile

遇到问题:

  • oauth.js 一般都会调用 service 进行存储,目前的方式无法支持
  • oauth.js 的 API 都是 callback 方式的,不优雅

建议提案

主插件 egg-oauth2-server

职责:

  • 类似 egg-view 和 egg-passport,提供统一的约定和挂载方式
  • 提供 app.oauth2Server.use(StrategyClass)
    • use 里面可以调用 loadToContext 等把 class 注册到 ctx
  • 提供 app.oauth2Server.Strategy 基类
    • interface 设计都改为 promise 或 generator 类

用户使用方式

// {app_root}/app.js
module.exports = app => {
  const Strategy = require('./lib/oauth2_strategy');
  app.oauth2Server.use(Strategy);
}

// {app_root}/lib/oauth2_strategy.js
module.exports = app => {
  return class MyStrategy extends app.oauth2Server.Strategy {
    constructor(ctx) {
      super(ctx);
    }

    * getAccessToken() {
      return yield ctx.service.xxx();
    }
  }
}

进一步扩展

  • 上面的 oauth2_strategy.js 可以独立为二级插件的方式
  • 即根据不同的业务场景,封装 egg-oauth2-server-firebase / egg-oauth2-server-alibaba
  • 应用开发者直接安装主插件和二级插件,然后在 app.jsuse 下即可
// {app_root}/app.js
module.exports = app => {
  const Strategy = require('./lib/oauth2_strategy');
  app.oauth2Server.use(Strategy);
}

// {app_root}/lib/oauth2_strategy.js
module.exports = app => {
  return class MyStrategy extends app.oauth2Server.Strategy {
    constructor(ctx) {
      super(ctx);
    }

    * getAccessToken() {
      return yield ctx.service.xxx();
    }
  }
}

accessTokenLifetime 配置无效

config/config.default.js

oAuth2Server: {
  debug: true,
  grants: [ 'password', 'authorization_code', 'refresh_token' ],
  accessTokenLifetime: 7200,
  refreshTokenLifetime: 1209600
}

get token response

{
"accessToken": "1a4e7b8531f274fce992d33cabe62b4545327e7f",
"accessTokenExpiresAt": "2018-10-15T04:03:13.164Z",
"refreshToken": "b9c95fba7f1e9112e12d0f25ead5162e88c305a3",
"refreshTokenExpiresAt": "2018-09-29T04:03:13.164Z",
...
}

accessTokenExpiresAt 比createdAt时间大了一个月

有关client grants属性的问题

您好:
想请教一下
AuthorizeHandler.prototype.getClient = function(request) {
var clientId = request.body.client_id || request.query.client_id;

if (!clientId) {
throw new InvalidRequestError('Missing parameter: client_id');
}

if (!is.vschar(clientId)) {
throw new InvalidRequestError('Invalid parameter: client_id');
}

var redirectUri = request.body.redirect_uri || request.query.redirect_uri;

if (redirectUri && !is.uri(redirectUri)) {
throw new InvalidRequestError('Invalid request: redirect_uri is not a valid URI');
}
return promisify(this.model.getClient, 2).call(this.model, clientId, null)
.then(function(client) {
if (!client) {
throw new InvalidClientError('Invalid client: client credentials are invalid');
}

  if (!client.grants) {
    throw new InvalidClientError('Invalid client: missing client `grants`');
  }

  if (!_.includes(client.grants, 'authorization_code')) {
    throw new UnauthorizedClientError('Unauthorized client: `grant_type` is invalid');
  }

  if (!client.redirectUris || 0 === client.redirectUris.length) {
    throw new InvalidClientError('Invalid client: missing client `redirectUri`');
  }

  if (redirectUri && !_.includes(client.redirectUris, redirectUri)) {
    throw new InvalidClientError('Invalid client: `redirect_uri` does not match client value');
  }
  return client;
});

};
在鉴权第一步的时候,首先会调用getClient方法获取我们注册的app信息,这里会验证grants这个属性,我不太理解这个属性到底有什么含义,或者说是他的意义体现在哪里?
因为我现在也在做一个鉴权的服务,其中应用信息是另一个项目进行创建注册的,在创建应用的时候,grants这个属性现在是必须要的,而且值也是固定的几个值,就是不太理解为什么要验证这个属性

How to use authenticate() as global middleware?

when use egg-oauth2-server plugin as global middleware:

// app/middleware/auth.js

module.exports = options => {
  return async (ctx, next) => {
    try {
      const auth = await ctx.app.oAuth2Server.authenticate();
      console.log(auth); 
      await next();
    } catch (err) {
      ctx.logger.error(err);
    }
  };
};
// config/config.default.js

config.middleware = [ 'auth' ];

then output: [AsyncFunction]

when use authenticate() in egg controller:

// app/controller/debug.js

async index() {
  const { app, ctx } = this;
  const res = await app.oAuth2Server.authenticate();
  ctx.body = res;
}

then throw:

{
  "code": "ERR_INVALID_ARG_TYPE",
  "message": "The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. Received type undefined",
  "stack": "TypeError [ERR_INVALID_ARG_TYPE]: The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. Received type undefined\n    at Function.byteLength (buffer.js:494:11)\n    at respond (D:\\Develop\\projects\\zhifu\\api2\\node_modules\\koa\\lib\\application.js:245:25)\n    at handleResponse (D:\\Develop\\projects\\zhifu\\api2\\node_modules\\koa\\lib\\application.js:149:34)\n    at processTicksAndRejections (internal/process/task_queues.js:85:5)",
  "name": "TypeError",
  "status": 500
}

Is implicit grant mode supported?

node-oauth2-server support implicit grant mode now, so is this plugin supported? BTW, if I want to use more than one mode, how do I define the router?

the ctx of Model can't be changed

this.ctx can't be changed on each request after constructed.

module.exports = (app) => {
  class Model {
    constructor(ctx) {
      this.ctx = ctx;
    }
    test() {
      console.log(this.ctx.request.query);
    }
  }
  return Model;
};

几点建议

非常赞,感谢回馈。

以下是几点建议:

  • 配置修改exports['oauth2-server'] 改为 exports.oauth2Server
  exports.oauth2Server = {
    debug: process.env.NODE_ENV !== 'production',
    grants: [ 'password' ],
    model: oauth_model(app),
  };
  • 插件也修改为
exports.oauth2Server = {
  enable: true,
  package: 'egg-oauth2-server',
};
  • model 不用用户手动初始化,通过 Loader API 自动加载,可以参考 egg-sequelizeegg-view-nunjucks 的实现

  • app.js 里面的 console.log 可以改为 app.coreLogger,参见 日志

  • debug: process.env.NODE_ENV !== 'production' 可以考虑直接读取 app.config.env === 'local' 做转换

  • agent.js 没用可以去掉

  • index.js 也是多余的,你是用了 simple 那个 boilerplate ?应该用 plugin 那个,建议用 egg-boilerplate-plugin 重新初始化下,现在看到有不少不需要的代码,如 package.json 的 scripts 等。

token存储位置

我想问下,这个token的存储是存储在数据库里面吗 如果多台服务器要怎么取出这个token相关信息

请教一个问题

请问调用authorize()这个函数,目前是把网页直接返回,有没有办法返回URL

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.