colinskow / superlogin

Powerful authentication for APIs and single page apps using the CouchDB ecosystem which supports a variety of providers.
MIT License
371 stars 117 forks source link

Superlogin Token and Password not valid credentials for Bluemix Cloudant #182

Closed turnono closed 7 years ago

turnono commented 7 years ago

Hi, as I am still new to this so the problem is probably something simple but I just can't figure it for the past 3 days now.

Im using Superlogin in Ionic 2 with pouchDB. The server is deployed on Heroku (the config variables is my Cloudant details).

The login works and the session appears on the Cloudant website, but the token and password created by Superlogin does not allow me to access the Cloudent database from within the app (the error is 403. I get the same error if I try it from Postman with this token and password).

This is the login function:

this.db = new PouchDB('halaal');

 login(){

    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    headers.append( "Authorization", "Bearer {token}:{password}");

    let credentials = {
      username: this.username,
      password: this.password
    };

    this.http.post('https://slogin.herokuapp.com/auth/login', JSON.stringify(credentials), {headers: headers})
      .subscribe(res => {
       this.db.sync( res.json().userDBs.halaal);
        }
      }, (err) => {
        console.log(err);
      });
  }

The server code:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var http = require('http');
var app = express();
var cors = require('cors');
var SuperLogin = require('superlogin');
var superloginConfig = require('./superlogin.config.js');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
// Redirect to https except on localhost
app.use(httpsRedirect);

app.use(express.static(path.join(__dirname, '../client/www')));
app.use(logger('dev'));

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header('Access-Control-Allow-Methods', 'DELETE, PUT');
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

// load SuperLogin routes
var superlogin = new SuperLogin(superloginConfig);
app.use('/auth', superlogin.router);
superlogin.addUserDB("bilal","queryout","shared");

app.use('*', function(req, res) {
  res.sendFile('index.html', {root: path.join(__dirname, '../client/www')});
});

module.exports = app;

The superlogin.config.js code

console.log(__dirname);
module.exports = {
  security: {
    maxFailedLogins: 3,
    lockoutTime: 600,
    tokenLife: 86400,
    loginOnRegistration: true,
    defaultRoles: ['user']
  },
  dbServer: {
    protocol: process.env.DB_HOST ? 'https://' : 'http://',
    host: process.env.DB_HOST || 'localhost:5984',
    user: process.env.DB_USER,
    password: process.env.DB_PASS,
    // automatically detect if the host is Cloudant
    cloudant: process.env.DB_HOST && process.env.DB_HOST.search(/\.cloudant\.com$/) > -1,
    userDB: 'sl-users',
    couchAuthDB: '_users'
  },
   userDBs: {
    defaultDBs: {
      shared: ['halaal','queryin']
    },
    model: {
      halaal: {
        permissions: ['_reader'],
        type: 'shared'
      },
      queryin: {
        permissions: ['_writer'],
        type: 'shared'
      },
      queryout: {
        permissions: ['_writer','_reader','_replicator'],
        type: 'shared'
      }
    }
  }
  }
};
peteruithoven commented 7 years ago

This is really more a stackoverflow question than a concrete issue? I would recommend comparing your code (and network traffic) with the superlogin-demo and/or the superlogin-client code. I also think you could simplify your example, to make it an easier to understand. For example the config for social login providers and the custom Redis config.

osaruagbonaye commented 7 years ago

Am not sure about this headers.append( "Authorization", "Bearer {token}:{password}");

Where is token and password getting their values from?

osaruagbonaye commented 7 years ago

I dont think you should enable authorization for login since one of the reasons for login is to get authorization

You can check your server code and remove this part that requires authorization on login "superlogin.requireAuth"

if you need to set authorization header in other part of your app, You can set authorization header like this headers.append( "Authorization", Bearer ${details.token}:${details.password}); I am assuming the details object contain token and password field: the details might be a return value from register or login routes

turnono commented 7 years ago

Seems this was a Cloudant issue, the code I posted does work. I recreated the DBs on Cloudant and everything worked. Thanks so much