Git Product home page Git Product logo

node-oauth2-server-implementation's Introduction

Node OAuth2 Server Implementation

Please refer this Fully functional OAuth 2.0 Implementation with production example with node-oauth2-server#2.4.0

Supports "oauth2-server": "^3.0.0-b2",

Installation

git clone https://github.com/manjeshpv/node-oauth2-server-implementation
npm install
npm start or node ./bin/www

Quick Start

The module provides two middlewares, one for authorization and routing, another for error handling, use them as you would any other middleware:

var express = require('express');
var oauthServer = require('oauth2-server');
var Request = oauthServer.Request;
var Response = oauthServer.Response;
var authenticate = require('./components/oauth/authenticate')

var app = express();

app.use(bodyParser.urlencoded({ extended: true }));

app.use(bodyParser.json());

// https://github.com/manjeshpv/node-oauth2-server-implementation/blob/master/components/oauth/models.js
var oauth = new oauthServer({
  model: require('./models.js')
});

app.all('/oauth/token', function(req,res,next){
    var request = new Request(req);
    var response = new Response(res);

    oauth
      .token(request,response)
      .then(function(token) {
        // Todo: remove unnecessary values in response
        return res.json(token)
      }).catch(function(err){
        return res.status( 500).json(err)
      })
  });

  app.post('/authorise', function(req, res){
    var request = new Request(req);
    var response = new Response(res);

    return oauth.authorize(request, response).then(function(success) {
        res.json(success)
    }).catch(function(err){
      res.status(err.code || 500).json(err)
    })
  });

app.get('/secure', authenticate(), function(req,res){
  res.json({message: 'Secure data'})
});

app.get('/me', authenticate(), function(req,res){
  res.json({
    me: req.user,
    messsage: 'Authorization success, Without Scopes, Try accessing /profile with `profile` scope',
    description: 'Try postman https://www.getpostman.com/collections/37afd82600127fbeef28',
    more: 'pass `profile` scope while Authorize'
  })
});

app.get('/profile', authenticate({scope:'profile'}), function(req,res){
  res.json({
    profile: req.user
  })
});

app.listen(3000);

After running with node, visting http://127.0.0.1:3000 should present you with a json response saying your access token could not be found.

To simulate, Use Postman: https://www.getpostman.com/collections/37afd82600127fbeef28

Features

  • Supports authorization_code, password, refresh_token, client_credentials and extension (custom) grant types
  • Implicitly supports any form of storage e.g. PostgreSQL, MySQL, Mongo, Redis...
  • Full test suite

Model Specification

See SQL file in /sql folder

The module requires a model object through which some aspects or storage, retrieval and custom validation are abstracted. The last parameter of all methods is a callback of which the first parameter is always used to indicate an error.

Note: see https://github.com/manjeshpv/node-oauth2-server-implementation/blob/master/components/oauth/models.js for a full model example using MySQL.

References: https://github.com/dsquier/oauth2-server-php-mysql

node-oauth2-server-implementation's People

Contributors

netbofia avatar sheershoff 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-oauth2-server-implementation's Issues

Q: using this with ember-simple-auth

I am upgrading node-oauth2-server from previous version (v 2) to this implementation. In order for this implementation to work with the existing simple-ember-auth (which worked with v2 of the node-oauth2-server), I am putting this on the server side

...
        var request = new Request(req);
        request.body.response_type = 'code';
        request.body.client_id = 'MY CLIENT';
        request.body.state = 'MY STATE';
        request.body.redirect_uri = 'MY REDIRECT URL';

        var response = new Response(res);

        return oauth.authorize(request, response).then(function(success) {
...

Could you suggest where am I supposed to set the response_type, client_id, state and redirect_url in ember-simple-auth?

Thanks.

Invalid scope: Requested scope is invalid

Hi,

I have just imported your project, added tables in database, configured the MariaDB connection and imported your Postman collection, but when i try your "Password Grant" call in Postman, i have this error :

{
  "message": "Invalid scope: Requested scope is invalid",
  "code": 400,
  "name": "invalid_scope"
}

An idea ?

best regards

Error 503: `accessTokenExpiresAt` must be a Date instance while

Hi, I've successfully get access token using Password Grant. When I try to use the access token to access secured pages, I got this error:
{
"statusCode": 503,
"status": 503,
"code": 503,
"message": "Server error: accessTokenExpiresAt must be a Date instance",
"name": "server_error"
}

I'm using this library with Mongo Model, using Dockerized Mongo DB Version 3.4.4

Any idea how to solve this?

Add Host obj to Config.js

Config.js does not have the 'host' object for specifying the MySQL IP/host.
Add:
sql: {
host: ''
...
}

Test Suite - Mocha, Postman, Curl

Postman

https://www.getpostman.com/collections/37afd82600127fbeef28

curl

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -H "Cache-Control: no-cache" -H "Postman-Token: c3df2fab-440f-09e4-0c5c-c9f46ef9836b" -d 'username=foo&password=bar&grant_type=password&client_id=publicClientId&client_secret=secretClientSecret' "http://localhost:3000/oauth/token"
curl -X GET -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Bearer YOUR_TOKEN" -H "Cache-Control: no-cache" -H "Postman-Token: 0f69e823-de90-b56e-265f-1c8ed5a57de2" "http://localhost:3000/"

oauthjs/node-oauth2-server#388

Suggestion for authenticate handler override

Hello,

It took me some time to grasp the concepts behind the authorize flow, and overriding the authenticate handler. There are numerous threads about this in the node-oauth2-server project, as I'm sure you are aware. I think even if your example included this commented out, this might be helpful?

Something like this?

oauth.authorize(request, response, {
      authenticateHandler: {
        handle: function(req, res) {
          if (req.body.userId) {
            // return full user object if necessary, otherwise just the ID
            return req.body.userId;
          }
          else {
            // redirect to login form
          }
        }
      }
    })
    .then(function(success) {
      console.log("SUCCESS", success);
      cb(false, success);
    })
    .catch(function(err) {
      console.log("AUTH ERR", err);
      cb(err);
    })

Insufficient scope: authorized scope is insufficient

i have made request from postman to localhost:3000/profile

with header : Authorization : Bearer {{AccessToken}}

got this response

{
    "statusCode": 403,
    "status": 403,
    "code": 403,
    "message": "Insufficient scope: authorized scope is insufficient",
    "name": "insufficient_scope"
}

Server error

{"message":"Server error: missing client grants","code":503,"name":"server_error"}

TOKEN lifetime

Hi,

I tried to set lifetime token, but the application keeps (60 * 60) from default settings

function getClient(clientId, clientSecret) {
  console.log("getClient",clientId, clientSecret)
  const options = {client_id: clientId};
  if (clientSecret) options.client_secret = clientSecret;

  return OAuthClient
    .findOne(options)
    .then(function (client) {
      if (!client) return new Error("client not found");
      var clientWithGrants = client
      clientWithGrants.grants = ['authorization_code', 'password', 'refresh_token', 'client_credentials']
      // Todo: need to create another table for redirect URIs
      clientWithGrants.redirectUris = [clientWithGrants.redirect_uri]
      delete clientWithGrants.redirect_uri
      clientWithGrants.refreshTokenLifetime = 9600
      clientWithGrants.accessTokenLifetime  = 10
      return clientWithGrants
    }).catch(function (err) {
      console.log("getClient - Err: ", err)
    });
}

Password Grant - grant_type => password

Hi,

I noticed that invoking http://localhost:3000/oauth/token (POST) need to have Authorization: Basic encoded(client_id + ':' + client_secret) as part of the header. My concern now what if i only need to have an access token doesn't care the client_id and client_key is it possible to achieved in this case?

Sample:
{ method: 'POST',
uri: 'http://localhost:3000/oauth/token',
form:
{ grant_type: 'password',
username: 'testuser',
password: 'testpassword',
scope: 'profile' },
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Basic testuser:testpassword' } }

Sessions

changes in node module

function getSession(done){
  if(this.req.oauth.session_id){
    return done();
  }
  var self = this;
  //console.log(this.req.)
  return this.model.saveSession(this.req, function (err, session) {
      if (err) return done(error('session_get_error', false, err));
      self.req.oauth.session_id = session.id;
      done();
    });
}

see full changelist quezx/node-oauth2-server@7ae5895

saveSession(req, cb) {
    const ua = req.headers['user-agent'];

    const agent = useragent.parse(ua);
    const { id: userId } = req.user;
    const session = { user_id: userId  };

    if (agent) {
      Object.assign(session, {
        browser: agent.toAgent(),
        os: agent.os.toString(),
        device: agent.device.toString(),
      });
    }

    const ip = (req.headers['x-forwarded-for'] || req.connection.remoteAddress).split(',')[0];

    session.ip = ip;
    const geo = geoip.lookup(ip);
    if (geo) {
      const { country, region, city, ll, metro, zip } = geo;
      const [latitude, longitude] = ll;
      Object.assign(session, { latitude, longitude, country, region,
        city, metro, zip,
      });
    }

    // - Detailed Logging
    const browser = ua ? bowser._detect(ua) : { os: 'na' };

    return Session.create(session)
      .then(saved => {
        cb(null, saved.toJSON());
        return saved;
      })
      .catch(cb);
  },

Create or Generate New Access Token using Password Grant Type

Hi manjeshpv, Good day!

I have encountered an issue on creating new access token:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -H "Cache-Control:
no-cache" -H "Postman-Token: c3df2fab-440f-09e4-0c5c-c9f46ef9836b" -d "username=admin&password=admin
&grant_type=password&client_id=democlient&client_secret=democlientsecret" "http://localhost:3000/oauth/token"
{"message":"user is not defined","code":503,"name":"server_error","inner":{}}

I already updated the node-oauth2-server-implementaion repo on my local machine. I'm using mysql oauth_demo schema as is. Did i missed something? Thanks

503 - User is not defined

Hi, I'm having this error using MySQL. I've just changed the path to the database. Nothing else was changed. Any ideas?
{
"statusCode": 503,
"status": 503,
"code": 503,
"message": "user is not defined",
"name": "server_error",
"inner": {}
}

Error when get profile after success auth

SequelizeEagerLoadingError: User is not associated to OAuthAccessToken!
    at Function._getIncludedAssociation (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:583:13)
    at Function._validateIncludedElement (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:499:53)
    at options.include.options.include.map.include (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:395:37)
    at Array.map (<anonymous>)
    at Function._validateIncludedElements (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:390:39)
    at Promise.try.then.then (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:1576:14)
    at tryCatcher (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:794:20)
    at tryOnImmediate (timers.js:752:5)
    at processImmediate [as _immediateCallback] (timers.js:729:5)
SequelizeEagerLoadingError: User is not associated to OAuthAccessToken!
    at Function._getIncludedAssociation (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:583:13)
    at Function._validateIncludedElement (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:499:53)
    at options.include.options.include.map.include (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:395:37)
    at Array.map (<anonymous>)
    at Function._validateIncludedElements (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:390:39)
    at Promise.try.then.then (/home/dev06/projects/bb/server/node_modules/sequelize/lib/model.js:1576:14)
    at tryCatcher (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/home/dev06/projects/bb/server/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:794:20)
    at tryOnImmediate (timers.js:752:5)
    at processImmediate [as _immediateCallback] (timers.js:729:5)

How to get access token on new version

Hi all,

I am beginner here. How can I get access token on new version? I was using the old one and below is the sample code to get the token.

app.all('/oauth/token', app.oauth.grant());

app.get('/', app.oauth.authorise(), function (req, res) {
	res.send('Congratulations, you are in a secret area!');
});

Thanks in advance.

Postman Authorization Key Value

For the following three requests there is a hardcoded header valeu for Authorization key i.e. Basic ZGVtb2NsaWVudDpkZW1vY2xpZW50c2VjcmV0

  1. Password Grant
  2. Client Credentials Grant
  3. Refresh Token

What is this key used for? Can I change it? How?

About process

I want create Oauth 2.0 server, how to add multiple clients and users.

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.