我是Oauth和服务器端的新手,所以请耐心等待我.
我有一个使用dropbox-js对用户进行身份验证的Web应用程序.一切都非常简单.该应用程序使用dropBox-js的client.authenticate函数,如果用户通过身份验证,则应用程序会自动重定向到初始页面,执行身份验证回调.从那一刻起,我知道我很高兴使用DropBox进行身份验证,我可以使用应用程序的DropBox目录.
我有一个目前什么也没做的公共node.js服务器.我想做的是:
>一旦客户端通过身份验证,请调用我的服务器并告诉它用户已通过身份验证
>如果服务器数据库上不存在该用户,则为其创建一个条目用户数据库(我不需要详细说明来执行此操作).如果存在,则发回用户的关联数据.
我怎样才能以安全的方式做到这一点?我的意思是,服务器如何告诉用户是有效的DropBox用户?服务器是否应该使用用户凭据向DropBox进行身份验证?这些情况下的工作流程是什么?
解决方法
在身份验证过程结束时,您有一个访问令牌,用于调用API.如果客户端和服务器都需要调用API,则两者都需要具有访问令牌.
如果您今天正在进行身份验证客户端,您可以以某种方式拉出访问令牌(不确定它是否/如何从库中暴露,但它存在于某处并存储在本地存储中)并将其传递给服务器.然后,服务器可以使用它来调用/account/info
并获取经过身份验证的用户的DropBox用户ID.
另一种方法是反过来做.使用“代码流”(而不是“令牌流”)对用户进行身份验证,并首先在服务器上获取访问令牌.然后你可以将它传递给客户端并将其作为Dropbox.Client
constructor中的一个选项传递.我认为dropBox-js本身支持它,但是你自己也不难.这是一些原始的Express代码,用于登录用户并显示他或她的名字:
var crypto = require('crypto'),express = require('express'),request = require('request'),url = require('url'); var app = express(); app.use(express.cookieParser()); // insert your app key and secret here var appkey = '<your app key>'; var appsecret = '<your app secret>'; function generateCSRFToken() { return crypto.randomBytes(18).toString('base64') .replace(/\//g,'-').replace(/\+/g,'_'); } function generateRedirectURI(req) { return url.format({ protocol: req.protocol,host: req.headers.host,pathname: app.path() + '/callback' }); } app.get('/',function (req,res) { var csrfToken = generateCSRFToken(); res.cookie('csrf',csrfToken); res.redirect(url.format({ protocol: 'https',hostname: 'www.dropBox.com',pathname: '1/oauth2/authorize',query: { client_id: appkey,response_type: 'code',state: csrfToken,redirect_uri: generateRedirectURI(req) } })); }); app.get('/callback',res) { if (req.query.error) { return res.send('ERROR ' + req.query.error + ': ' + req.query.error_description); } // check CSRF token if (req.query.state !== req.cookies.csrf) { return res.status(401).send( 'CSRF token mismatch,possible cross-site request forgery attempt.' ); } else { // exchange access code for bearer token request.post('https://api.dropBox.com/1/oauth2/token',{ form: { code: req.query.code,grant_type: 'authorization_code',redirect_uri: generateRedirectURI(req) },auth: { user: appkey,pass: appsecret } },function (error,response,body) { var data = JSON.parse(body); if (data.error) { return res.send('ERROR: ' + data.error); } // extract bearer token var token = data.access_token; // use the bearer token to make API calls request.get('https://api.dropBox.com/1/account/info',{ headers: { Authorization: 'Bearer ' + token } },body) { res.send('Logged in successfully as ' + JSON.parse(body).display_name + '.'); }); // write a file // request.put('https://api-content.dropBox.com/1/files_put/auto/hello.txt',{ // body: 'Hello,World!',// headers: { Authorization: 'Bearer ' + token } // }); }); } }); app.listen(8000);