2014-10-10 92 views
0

我有一个nodejs应用服务器尝试访问我的组织onedrive上的文件。该应用程序在Azure中注册,我可以制作图形API调用并获取结果。当我试图把它挂在onedrive API无响应,API是:OneDrive for Business与NodeJS的Javascript访问无响应

https://-my.sharepoint.com/personal//_api/file

我用的是RESOURCEID“ https://-my.sharepoint.com”。在resoureid

'Authorization': 'Bearer ' + aToken, 
    'Accept': 'application/json;odata=minimalmetadata;charset=utf-8' 

我也尝试添加URL Azure中Office 365的SharePoint Online中:我也尝试Microsoft.SharePoint程序

我传递OAuth令牌像这样(在头) (http://office.microsoft.com/sharepoint/),但是这会返回错误资源未注册的帐户。


使用像这样对铬请求头一个REST工具:

接受:应用/ JSON 授权:承载eyJ0eXAiOiJKV1QiLCJhbGci ... 连接:保活 内容类型:应用程序/用户代理:Mozilla/5.0(Macintosh; Intel Mac OS X 10_9_5)AppleWebKit/537.36(KHTML,如Gecko)Chrome/38.0.2125.104 Safari/537.36

响应头:

Status Code: 200 
 
Date: Mon, 20 Oct 2014 18:53:55 GMT 
 
Content-Encoding: gzip 
 
Vary: Accept-Encoding 
 
X-AspNet-Version: 4.0.30319 
 
X-Powered-By: ASP.NET 
 
Transfer-Encoding: chunked 
 
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI" 
 
X-SharePointHealthScore: 0 
 
X-SP-SERVERSTATE: ReadOnly=0 
 
request-id: 5611c49c-b0b2-1000-8ca2-5acda39588a3 
 
MicrosoftSharePointTeamServices: 16.0.0.3312 
 
X-MS-InvokeApp: 1; RequireReadOnly 
 
Last-Modified: Mon, 20 Oct 2014 18:53:54 GMT 
 
Server: Microsoft-IIS/7.5 
 
SPRequestGuid: 5611c49c-b0b2-1000-8ca2-5acda39588a3 
 
X-FRAME-OPTIONS: SAMEORIGIN 
 
Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8 
 
Cache-Control: private, max-age=0 
 
SPClientServiceRequestDuration: 1642 
 
X-Content-Type-Options: nosniff 
 
Expires: Sun, 05 Oct 2014 18:53:54 GMT 
 

 
Request: 
 
Request Url: https://xxxx-my.sharepoint.com/personal/satish_ramjee_xxxxx_co_uk/_api/files 
 
Request Method: GET 
 
Status Code: 200 
 
Params: {}
此返回预期JSON对象


相关代码如下

'use strict'; 
 

 
var express = require('express'); 
 
var request = require('request'); 
 
var http = require('http'); 
 
var path = require('path'); 
 
var passport = require('passport'); 
 
var AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2'); 
 
var engine = require('ejs-locals'); 
 
var app = express(); 
 

 
var config = { 
 
    // Enter the App ID URI of your application. To find this value in the Windows Azure Management Portal, 
 
    // click Active Directory, click Integrated Apps, click your app, and click Configure. 
 
    // The App ID URI is at the bottom of the page in the Single Sign-On section. 
 
    realm: 'http://localhost:4000', 
 

 
    
 
    // Enter the endpoint to which your app sends sign-on and sign-out requests when using WS-Federation protocol. 
 
    // To find this value in the Windows Azure Management Portal, click Active Directory, click Integrated Apps, 
 
    // and in the black menu bar at the bottom of the page, click View endpoints. 
 
    // Then, copy the value of the WS-Federation Sign-On Endpoint. 
 
    // Note: This field is ignored if you specify an identityMetadata url 
 
    identityProviderUrl: 'https://login.windows.net/8b87af7d-8647-xxxxxxx/wsfed', 
 

 
    // Enter the logout url of your application. The user will be redirected to this endpoint after 
 
    // the auth token has been revoked by the WSFed endpoint. 
 
    logoutUrl: 'http:/localhost:4000/', 
 

 
    // Enter the URL of the federation metadata document for your app or the cert of the X.509 certificate found 
 
    // in the X509Certificate tag of the RoleDescriptor with xsi:type="fed:SecurityTokenServiceType" in the federation metadata. 
 
    // If you enter both fields, the metadata takes precedence 
 
    identityMetadata: 'https://login.windows.net/8b87af7d-8647-4dc7-xxxxxxxx/federationmetadata/2007-06/federationmetadata.xml' 
 
}; 
 

 

 
var graphConfig = { 
 
// Enter the domain for your Active directory subscription, such as contoso.onmicrosoft.com 
 
    tenant: '8b87af7d-8647-4dc7-xxxxxxxxxxxxxxx', 
 
    // Enter the Client ID GUID of your app. 
 
    // In the Windows Azure Management Portal, click Active Directory, click your tenant, 
 
    // click Integrated Apps, click your app, and click Configure. 
 
    // The Client ID is on this app configuration page. 
 
    clientid: '2462ee60-5695-xxxxxxxxxxxxxx', 
 

 
    //Enter the value of the key for the app. You can create the key on the Configure page for the app. 
 
    // The value appears only when you first save the key. Enter the saved value. 
 
    clientsecret: 'xxxxxxxxxxxxxxxx' 
 
}; 
 

 
// array to hold logged in users 
 
var users = []; 
 

 
// AAD Graph Client for AAD queries 
 
var graphClient = null; 
 
var aToken; 
 

 
// use ejs-locals for all ejs templates: 
 
app.engine('ejs', engine); 
 

 
app.configure(function(){ 
 
    app.set('port', process.env.PORT || 4000); 
 
    app.set('views',__dirname + '/views'); 
 
    app.set('view engine', 'ejs'); 
 
    app.use(express.favicon()); 
 
    app.use(express.logger('dev')); 
 
    app.use(express.bodyParser()); 
 
    app.use(express.methodOverride()); 
 
    app.use(express.cookieParser('your secret here')); 
 
    app.use(express.session({ secret: 'keyboard cat' })); 
 
    app.use(passport.initialize()); 
 
    app.use(passport.session()); 
 
    app.use(app.router); 
 
    app.use(express.static(path.join(__dirname, 'public'))); 
 
}); 
 

 
app.configure('development', function(){ 
 
    app.use(express.errorHandler()); 
 
}); 
 

 
var findByEmail = function (email, fn) { 
 
    for (var i = 0, len = users.length; i < len; i++) { 
 
    var user = users[i]; 
 
    if (user.email === email) { 
 
     return fn(null, user); 
 
    } 
 
    } 
 
    return fn(null, null); 
 
}; 
 

 

 
// Simple route middleware to ensure user is authenticated. 
 
// Use this route middleware on any resource that needs to be protected. If 
 
// the request is authenticated (typically via a persistent login session), 
 
// the request will proceed. Otherwise, the user will be redirected to the 
 
// login page. 
 
var ensureAuthenticated = function(req, res, next) { 
 
    if (req.isAuthenticated()) { 
 
    return next(); 
 
    } 
 
    res.redirect('/login'); 
 
}; 
 

 
//var RESOURCE = "https://graph.windows.net"; 
 
//var REST_CALL = 'https://graph.windows.net/' + graphConfig.tenant + '/Users()'; 
 
var RESOURCE = "https://xxxx-my.sharepoint.com"; 
 
var REST_CALL = "https://xxxx-my.sharepoint.com/personal/satish_ramjee_xxxxxx_co_uk/_api/files"; 
 

 
//passport.use(wsfedStrategy); 
 
passport.use(new AzureAdOAuth2Strategy ({ 
 
    clientID: graphConfig.clientid, 
 
    clientSecret: graphConfig.clientsecret, 
 
    tenant: graphConfig.tenant, 
 
    resource: RESOURCE, 
 
    callbackURL: "http://localhost:4000/callback", 
 
    }, 
 
    function(accessToken, refreshToken, params, profile, done) { 
 
     console.log("access token ---> " + accessToken); 
 
     aToken = accessToken; 
 
     console.log("done ---> " + JSON.stringify(done)); 
 
    
 
     var waadProfile = profile || jwt.decode(params.id_token, '', true); 
 
     console.log("waad ---> " + JSON.stringify(waadProfile)); 
 
    
 
//  _res.redirect("/ok"); 
 
//  User.findOrCreate({ id: waadProfile.upn }, function (err, user) { 
 
      return done(); 
 
//  }); 
 
})); 
 

 
var sp_files = function(callback) { 
 
    var headers = { 
 
     'Authorization': 'Bearer ' + aToken, 
 
     'Accept': 'application/json', 
 
    }; 
 

 
if (RESOURCE.indexOf("graph") != -1) { 
 
    headers[ 'x-ms-dirapi-data-contract-version'] = '0.5'; 
 
} 
 
    
 
    console.log("CALL___________________ "+REST_CALL); 
 
    request({ 
 
    url: REST_CALL, 
 
// qs: qs, 
 
    headers: headers 
 
    }, function(err, resp, body) { 
 
    console.log("Body " + body); 
 
     console.log("Err " + err); 
 
// if (err) return callback(err, null); 
 
     
 
    if (resp && resp.statusCode != 200) { 
 
     return callback(new Error(body), null); 
 
    } 
 
    else if (!resp) { 
 
     return callback(null, null); 
 
    } 
 

 
// { results: 
 
// [ { __metadata: [Object], 
 
//  Manager: [Object], 
 
//  DirectReports: [Object], 
 

 
    var d = JSON.parse(body).d, 
 
     users = d.results; 
 
//  meta = buildMetadata(d); 
 
     console.log("users" + users); 
 
     return callback(users); 
 
    }) 
 
    
 
    console.log("Sent request---->"); 
 
} 
 

 
http.createServer(app).listen(app.get('port'), function(){ 
 
    console.log("Express server listening on port " + app.get('port')); 
 
}); 
 

 
var graphQuery = function(res, user) { 
 
    graphClient.getUsers(function(err, result) { 
 
    if(err) { 
 
     res.end('GraphClient.getUsers error:' + err + '\n'); 
 
    } else { 
 
    
 
     console.log("User " + JSON.stringify(result)); 
 
     
 
     //res.render('index', { user: user, data: JSON.stringify(result) }); 
 
    } 
 
    // get user properties (user.DisplayName, user.Mail, etc.) 
 
    }); 
 
}; 
 

 
var doWaad = function(res, user) { 
 
    if(graphClient === null) { 
 
    waad.getGraphClientWithClientCredentials2(graphConfig.tenant, graphConfig.clientid, graphConfig.clientsecret, function(err, client) { 
 
     if(err) { 
 
     res.end('waad.getGraphClientWithClientCredentials2 error:' + err + '\n'); 
 
     } else { 
 
     graphClient = client; 
 
     graphQuery(res, user); 
 
     } 
 
    }); 
 
    } else { 
 
    graphQuery(res, user); 
 
    } 
 
}; 
 

 
app.get('/cb', function(req, res) { 
 
    console.log("cb"); 
 
}); 
 

 
app.get('/fail', function(req, res) { 
 
    console.log("fail"); 
 
}); 
 
app.get('/ok', function(req, res) { 
 
    console.log("*************** ok ", req.user); 
 
    //doWaad(res, req.user); 
 
}); 
 

 

 

 

 
app.get('/', function(req, res){ 
 
    if (aToken) { 
 
     console.log("T: " + aToken); 
 
     sp_files(function(d) { 
 

 
     var mail = []; 
 
      if (d) 
 
      for (var i=0; i< d.length; i++) { 
 
       console.log(i + ">>>> " + d[i]); 
 
//    if (d[i].Mail) 
 
//    mail.push(d[i].Mail); 
 
       if (d[i]) 
 
       mail.push(JSON.stringify(d[i])); 
 
      } 
 
      res.render('result', { user: d, data: mail, oauth: aToken}); 
 
     }); 
 
     
 
    } else { 
 
    res.render('index', { user: null}); 
 
    } 
 
}); 
 

 
app.get('/account', ensureAuthenticated, function(req, res){ 
 
    res.render('account', { user:req.user }); 
 
}); 
 

 

 

 
app.get('/login', 
 
    passport.authenticate('azure_ad_oauth2', { 
 
    failureRedirect: '/fail' 
 
    }) 
 
); 
 

 

 

 
app.get('/callback', 
 
    passport.authenticate('azure_ad_oauth2', { failureRedirect: '/', failureFlash: true }), 
 
    function(req, res) { 
 
     // Successful authentication, redirect home. 
 
    console.log("================= callback"); 
 
     res.redirect('/ok'); 
 
    } 
 
); 
 

 

 
app.get('/logout', function(req, res){ 
 

 
// clear the passport session cookies 
 
    req.logout(); 
 

 
// We need to redirect the user to the WSFED logout endpoint so the 
 
// auth token will be revoked 
 
    wsfedStrategy.logout({}, function(err, url) { 
 
    if(err) { 
 
     res.redirect('/'); 
 
    } else { 
 
     res.redirect(url); 
 
    } 
 
    }); 
 
}); 
 

 
// Passport session setup. 
 
// To support persistent login sessions, Passport needs to be able to 
 
// serialize users into and deserialize users out of the session. Typically, 
 
// this will be as simple as storing the user ID when serializing, and finding 
 
// the user by ID when deserializing. 
 
passport.serializeUser(function(user, done) { 
 
    done(null, user.email); 
 
}); 
 

 
passport.deserializeUser(function(id, done) { 
 
    findByEmail(id, function (err, user) { 
 
    done(err, user); 
 
    }); 
 
});

这是主要的app.js节点代码,它适用于图形api,但不适用于sharepoint api。一旦收到令牌,就会调用函数sp_files发出https请求。共享点调用挂起没有响应,虽然这是JavaScript,但它仍然是服务器端,所以跨域问题应该在这里不相关。

+0

BTW的RESTAPI我使用https:// -my.sharepoint.com/personal/ _co_uk/_api /文件工作正常从布劳尔 – LightPhos 2014-10-10 10:19:41

+0

你可以复制和粘贴在这里的提琴手跟踪以及以确保标题肯定正在被推送? – 2014-10-20 16:26:23

+0

由于您可以从Fiddler调用这些API,因此发布您用于调用SPO的代码也会很有帮助。 – 2014-10-21 01:02:40

回答

2

好吧,搞清楚了这个问题,SharePoint在不支持TLS的IIS上运行,但支持SSLv3。 NodeJS使用TLS通过蔑视,我改变它使用SSLv3,它现在工作。

但不幸的是,不幸的是,SSLv3最近被发现容易受到POODLE MITM攻击。