Angularjs CORS与Node,Express,Oauth2和Passport有关

最近我们决定把我们的前端从EJS切换到Angular将前端和后端完全分开。 这样做,我们开始在多个浏览器中遇到几个问题。 在后端,我们使用快递的节点与护照和oauth2。 对于前端我们正在尝试使用angular度。 EJS使用express.render工作,但我们更愿意直接使用express作为RESTful API。

我在localhost:8080和localhost:3000本地运行后端和前端。 当只使用后端(使用EJS,而不是angular度),我可以成功地去浏览器的后端端口,通过passport-oauthlogin,并redirect到帐户页面(从供应商login屏幕),我的JSON数据通过res.json呈现。 问题是我无法从移除EJS后从前端用户界面。

我已经试过configurationCORS十几种不同的方式,而使用三种不同的浏览器,没有运气。 以下三个片段是我在浏览器控制台中通过$ http和$ resource从前端访问localhost:8080时出现的错误(请参阅下面的代码)。 三个代码片段下面的图片是节点控制台告诉我,当试图从每个不同的浏览器访问端口8080 …

铬:

XMLHttpRequest cannot load 'PROVIDER-DETAILS-URL'. No 'Access-Control-Allow- Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. 

火狐:

 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at 'PROVIDER-DETAILS-URL'. (Reason: CORS header 'Access-Control-Allow-Origin' missing). Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at 'PROVIDER-DETAILS-URL'. (Reason: CORS request failed). 

苹果浏览器:

 XMLHttpRequest cannot load http://localhost:8080/auth/PROVIDER. Request header field Accept-Encoding is not allowed by Access-Control-Allow-Headers. 

控制台图像: 在这里输入图像描述

和代码:

服务器:

app.js

 'use strict'; const express = require('express'); const session = require('express-session'); const cookieParser = require('cookie-parser'); const bodyParser = require('body-parser'); const logger = require('morgan'); const errorHandler = require('errorhandler'); const path = require('path'); const flash = require('connect-flash'); const passport = require('passport'); const expressValidator = require('express-validator'); /** * Load environment variables, where API keys and passwords are configured. */ const config = require('./config/config'); /** * Route Handlers */ const index = require('./routes/index'); const account = require('./routes/account'); const logout = require('./routes/logout'); /** * API keys and Passport configuration. */ const passportConfig = require('./strategy'); /** * Create Express server. */ const app = express(); /** * Express configuration. */ app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization"); res.header("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT"); next(); }); app.use(cookieParser()); app.use(expressValidator()); app.use(session({ resave : true, saveUninitialized : true, secret : config.sessionSecret, })); app.use(passport.initialize()); app.use(passport.session()); app.use(flash()); /** * Primary app routes. */ app.get('/', index.execute); app.get('/account', passportConfig.isAuthenticated, account); app.get('/logout', logout.execute); /** * OAuth authorization routes. */ app.get('/auth/PROVIDER', passport.authenticate('PROVIDER')); app.get('/auth/PROVIDER/callback', passport.authenticate('PROVIDER', { failureRedirect : '/'}), function(req, res) { res.redirect('/account'); }); /** * Error Handler. */ app.use(errorHandler()); /** * Start Express server. */ app.listen(8080, () => { console.log('App listening on port 8080'); }); module.exports = app; 

strategy.js

 'use strict'; const passport = require('passport'); const session = require('express-session'); const config = require('./config/config'); const OAuth2Strategy = require('passport-oauth').OAuth2Strategy; /** * Put together the right header info for PROVIDER */ var authString = new Buffer(config.PROVIDER.clientID + ':' + config.PROVIDER.clientSecret); var customHeader = { "Authorization": "Basic " + authString.toString('base64') }; /** * OAuth2Strategy containing the customHeader created above. */ passport.use('PROVIDER', new OAuth2Strategy({ authorizationURL : config.PROVIDER.authorizationURL, tokenURL : config.PROVIDER.tokenURL, clientID : config.PROVIDER.clientID, clientSecret : config.PROVIDER.clientSecret, callbackURL : config.PROVIDER.callbackURL, customHeaders : customHeader, passReqToCallback : true }, function( req, accessToken, refreshToken, profile, done ) { req.session.accessToken = accessToken; return done(null, profile); } )); passport.serializeUser(function(user, done) { return done(null, user); }); passport.deserializeUser(function(obj, done) { return done(null, obj); }); /** * Login Required middleware. */ exports.isAuthenticated = function(req, res, next) { if (req.isAuthenticated()) { console.log('isAuthenticated'); return next(); } res.redirect('/'); }; /** * Authorization Required middleware. */ exports.isAuthorized = function(req, res, next) { var provider = req.path.split('/').slice(-1)[0]; if (_.find(req.user.tokens, { kind: provider })) { next(); } else { res.redirect('/auth/' + provider); } }; 

index.js

 exports.execute = function (req, res) { if (req.user) { console.log('========== ROUTES/INDEX.JS | 3 =========='); res.redirect('/account'); } else { console.log('========== ROUTES/INDEX.JS | 6 =========='); res.redirect('/auth/PROVIDER'); } }; 

客户:

我把它结合起来,使它更容易阅读。

 angular.module('StackOverflowPost', []) .factory('APIService', function() { function getData( $q, $http ) { var defer = $q.defer(); $http.get( 'localhost:8080' ) .success( getDataComplete ) .catch( getDataFailed ); function getDataComplete( response ) { console.log( response.Authorization ); defer.resolve(response.data.results ); } function getDataFailed( error ) { console.log( error.data ); defer.reject( 'XHR Failed for getData - ' + error.data ); } return defer.promise; } }) .controller('MainCtrl', function( APIService ) { var vm = this; vm.getDataTest = function() { APIService.getData().then(function( returnedData ) { console.log( returnedData ); }) } }); 

任何帮助或方向将不胜感激。

更新 (4/28/2016) :我更新了原始post的更多细节。 我也更新了代码,以便在经过一个星期的反复试验之后。

请检查这个

https://gist.github.com/dirkk0/5967221

代码应该是

 // in AngularJS (client) myApp.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; }]); // in Express/nodeJS // in NodeJS/Express (server) app.all('/*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "X-Requested-With"); res.header("Access-Control-Allow-Methods", "GET, POST","PUT"); next(); });