我正在开发使用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中具有配置
我的代码中缺少什么。如何获取成功状态并获取用户信息