简体   繁体   English

Angularjs CORS遇到Node,Express,Oauth2和Passport的麻烦

[英]Angularjs CORS trouble with Node, Express, Oauth2, and Passport

Recently we have decided to switch our front-end from EJS to Angular separate the frontend and the backend completely. 最近,我们决定将前端从EJS切换到Angular,将前端和后端完全分开。 In doing so, we started to run into several issues across multiple browsers. 为此,我们开始在多个浏览器中遇到多个问题。 On the back end we are using Node with express along with passport and oauth2. 在后端,我们使用带有express的Node以及护照和oauth2。 For the front end we are attempting to use angular. 对于前端,我们尝试使用angular。 EJS works using express.render, but we would prefer to use angular directly by utilizing express as just a RESTful API. EJS使用express.render进行工作,但我们希望直接将express作为RESTful API来直接使用angular。

I'm running both the backend and frontend locally at localhost:8080 and localhost:3000, respectfully. 我分别在本地主机:8080和本地主机:3000上运行后端和前端。 When just working with the backend (USING EJS, NOT ANGULAR), I can successfully go to our backend port in the browser, login via passport-oauth, and be redirect to the account page (from the providers login screen) where my json data is rendered via res.json. 当仅使用后端(使用EJS,不是ANGULAR)时,我可以成功地进入浏览器中的后端端口,通过Passport-oauth登录,然后重定向到帐户页面(从提供商登录屏幕),其中存放我的json数据通过res.json呈现。 The problem is I am unable to do this from the frontend UI after removing EJS. 问题是删除EJS之后,我无法从前端UI进行此操作。

I've tried configuring CORS a dozen different ways while using three different browsers with no luck. 我尝试过使用三种不同的浏览器,但运气不好,以多种方式配置了CORS。 The following three snippets are the errors I'm getting in the browsers console while trying to access localhost:8080 from the frontend via $http and $resource (see below for the code). 以下三个代码段是我尝试通过$ http和$ resource从前端访问localhost:8080时在浏览器控制台中遇到的错误(请参见下面的代码)。 The image below the three code snippets is what the node console is telling me when trying to access port 8080 from each different browser... 尝试从每个不同的浏览器访问端口8080时,节点控制台告诉我这三个代码段下方的图像...

Chrome: 铬:

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.

Firefox: 火狐:

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).

Safari: 苹果浏览器:

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

Console Image: 控制台映像: 在此处输入图片说明

And the code: 和代码:

Server: 服务器:

app.js 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 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 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');
    }
};

Client: 客户:

I combined this to make it a little easier to read. 我将其结合起来使其更易于阅读。

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 );
        })
    }
});

Any help or direction would be greatly appreciated. 任何帮助或指示将不胜感激。

UPDATE (4/28/2016) : I updated the original post with more details. 更新 (4/28/2016) :我更新了原始帖子,并提供了更多详细信息。 I also updated the code to what it is after another week of trial and error. 经过一周的反复试验,我还将代码更新为现在的代码。

Please check this 请检查一下

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

Code should be 代码应该是

// 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();

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Angular + Node + Express + Passport + oAuthorizeor独特的CORS问题 - Angular + Node + Express + Passport + oauth2orize unique CORS issues 需要使用护照的飞行前CORS表示angularjs - CORS that require preflight, using passport, express angularjs AngularJS的NodeJS OAuth2 CORS问题 - NodeJS OAuth2 CORS issue with AngularJS Angular JS + Node JS + Passport + Spring OAuth2身份验证/授权 - Angular JS + Node JS + Passport + Spring OAuth2 Authentication/Authorization 使用node.js / express和AngularJS的CORS请求 - CORS requests with node.js/express and AngularJS Angular / Node / Express / Passport - 连接到facebook(CORS)时出现问题 - Angular/Node/Express/Passport - Issues when connecting to facebook(CORS) Angular / Node / Express / Passport跨域问题 - 启用CORS Passport Facebook身份验证 - Angular/Node/Express/Passport Cross Domain Problems - Enable CORS Passport Facebook Authentication Spring-boot-oauth2-angularjs,会话到期后CORS错误并重定向到oauth2服务器 - Spring-boot-oauth2-angularjs, error with CORS after session expiry and redirect to oauth2 server 如何通过护照为AngularJS和Laravel应用创建基于令牌的身份验证(oauth2) - How to create Token-Based Authentication(oauth2) for AngularJS and Laravel Apps via passport CORS与nodejs和AngularJS有关 - CORS trouble with nodejs and AngularJS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM