使用Loopback Passport组件登录Google总是回调失败

时间:2019-05-16 10:34:13

标签: javascript passport.js loopback google-login

我正在开发使用Loopback-passport-component的服务器,以将第三方登录集成为Google,Facebook。 但是我总是在用户登录他们的Google帐户后从Google接收失败回调。

这是我的服务器代码:

    'use strict';
var loopback = require('loopback');
var boot = require('loopback-boot');

var path = require('path');
var app = module.exports = loopback();

var bodyParser = require('body-parser');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var flash = require('express-flash');

//create an instance of PassportConfigurator with the app instance
const PassportConfigurator = require('loopback-component-passport').PassportConfigurator;
const passportConfigurator = new PassportConfigurator(app);


app.middleware('initial', bodyParser.urlencoded({ extended: true }));

app.use('/express-status', function (req, res, next) {
    res.json({ running: true });
});

//custom access token model
app.use(loopback.token({
    model: app.models.AccessTokens,
    currentUserLiteral: 'me'
}))
app.set('view engine', 'html');
app.set('views', __dirname + '/views');

//to support JSON encoded bodies
app.middleware('parse', bodyParser.json());
// to support URL-encoded bodies
app.middleware('parse', bodyParser.urlencoded({
    extended: true
}));

//enable http session
app.middleware('session:before', cookieParser('MY SECRET'));
app.middleware('session', session({
    secret: 'secret',
    saveUninitialized: true,
    resave: true
}))

//load the provider configurations
var config = {};
try {
    config = require('../provider.json');

} catch (err) {
    console.error('please configure your passport strategy in provider.json');
    console.trace(err);
    process.exit(1);
}

//Initialize passport
passportConfigurator.init();

// We need flash messages to see passport errors
app.use(flash());

var ensureLoggedIn = require('connect-ensure-login').ensureLoggedIn;

app.get('/auth/account', ensureLoggedIn('/login'), (req, res, next) => {
    console.log('/auth/account');
    console.log('user ', req.user);
    res.json({ done: 'done auth account' });
})
app.get('/login', function (req, res, next) {
    console.log('login')
    res.json({ result: 'failure, redirec to login ' })
});
app.start = function () {

    //Get the FQPN of the index file in client
    var staticFolder = path.dirname(
        path.resolve(__dirname, '..', app.get('indexFile'))
    );
    //set static folder as static in server
    app.use(loopback.static(staticFolder));

    passportConfigurator.setupModels({
        userModel: app.models.Users,
        userIdentityModel: app.models.userIdentity,
        userCredentialModel: app.models.userCredential,
    })

    for (var s in config) {
        var c = config[s];
        c.session = c.session !== false;
        passportConfigurator.configureProvider(s, c);
    }

    // start the web server
    return app.listen(function () {
        app.emit('started');
        var baseUrl = app.get('url').replace(/\/$/, '');
        console.log('Web server listening at: %s', baseUrl);
        if (app.get('loopback-component-explorer')) {
            var explorerPath = app.get('loopback-component-explorer').mountPath;
            console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
        }
    });
};

// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function (err) {
    if (err) throw err;

    // start the server if `$ node server.js`
    if (require.main === module)
        app.start();
});

这是provider.json文件,用于定义Passport的配置

{
    "local":{
        "provider":"local",
        "module": "passport-local",
        "usernameField": "email",
        "passwordField": "password",
        "authPath": "/api/users/auth/local",
        "successRedirect": "/api/users/auth/account",
        "failureRedirect": "/api/user/login",
        "failureFlash": true,
        "setAccessToken": true
    },
    "google-login": {
        "provider": "google",
        "module": "passport-google-oauth",
        "strategy": "OAuth2Strategy",
        "clientID": "my google client ID",
        "clientSecret": "client secret",
        "callbackURL": "/auth/google/callback",
        "authPath": "/api/users/auth/google",
        "callbackPath": "/auth/google/callback",
        "successRedirect": "/auth/account",
        "failureRedirect": "/login",
        "scope": ["email", "profile"],
        "failureFlash": true
    },
    "google-link": {
        "provider": "google",
        "module": "passport-google-oauth",
        "strategy": "OAuth2Strategy",
        "clientID": "my google client ID",
        "clientSecret": "client secret",
        "callbackURL": "/link/google/callback",
        "authPath": "/link/google",
        "callbackPath": "/link/google/callback",
        "successRedirect": "/auth/account",
        "failureRedirect": "/login",
        "scope": ["email", "profile"],
        "link": true,
        "failureFlash": true
    }
}

我已经扩展了一些内置模型,例如User,AccessToken,UserIdentity和UserCredential

Users.json

{
    "name": "Users",
    "plural": "users",
    "base": "User",
    "idInjection": true,
    "options": {
        "validateUpsert": true
    },
    "restrictResetPasswordTokenScope": true,
    "emailVerificationRequired": true,
    "excludeBaseProperties": [
        "realm"
    ],
    "hidden": [
        "password"
    ],
    "properties": {
        "name": {
            "type": "string",
            "required": true
        },
        "email": {
            "type": "string",
            "required": true
        },
        "password": {
            "type": "string",
            "required": true
        },
        "image_profile": {
            "type": "string"
        },
        "gender": {
            "type": "string"
        },
        "location": {
            "type": "string"
        },
        "user_rank": {
            "type": "number",
            "required": true,
            "default": 0
        },
        "is_third_party": {
            "type": "boolean",
            "required": true,
            "default": false
        },
        "is_active": {
            "type": "boolean",
            "required": true,
            "default": true
        },
        "created": {
            "type": "date",
            "required": true,
            "defaultFn": "now"
        },
        "modified": {
            "type": "date",
            "required": true,
            "defaultFn": "now"
        }
    },
    "validations": [],
    "relations": {
        "accessTokens": {
            "type": "hasMany",
            "model": "AccessTokens",
            "foreignKey": "userId",
            "option": {
                "disableInclude": true
            }
        },
        "identities": {
            "type": "hasMany",
            "model": "userIdentity",
            "foreignKey": "userId"
        },
        "credentials": {
            "type": "hasMany",
            "model": "userCredential",
            "foreignKey": "userId"
        }
    },
    "acls": [],
    "methods": {}
}

userIdentity.json

{
    "name": "userIdentity",
    "plural": "user-identity",
    "base": "UserIdentity",
    "idInjection": true,
    "options": {
        "validateUpsert": true
    },
    "properties": {},
    "validations": [],
    "relations": {
        "user": {
            "type": "belongsTo",
            "model": "Users",
            "foreignKey": "userId"
        }
    },
    "acls": [],
    "methods": {}
}

userCredential.json

{
    "name": "userCredential",
    "plural": "user-credential",
    "base": "UserCredential",
    "idInjection": true,
    "options": {
        "validateUpsert": true
    },
    "properties": {},
    "validations": [],
    "relations": {
        "user": {
            "type": "belongsTo",
            "model": "user",
            "foreignKey": "userId"
        }
    },
    "acls": [],
    "methods": {}
}

我也已经在Google控制台上注册了我的域。但是我总是从Google回调到/ login路由。在provider.json文件的failureRedirect中具有配置

我的代码中缺少什么。如何获取成功状态并获取用户信息

0 个答案:

没有答案