这可能以前曾被问过,所以向我道歉。
我建立了一个网站,并建立了一个API。将来,移动应用还将使用该API。我拥有两者,因此我很确定两腿和三腿的OAuth不适合我。该API的某些部分可供全世界使用,其他部分则受保护并需要用户帐户。为了简单起见,我仅使用https +基本身份验证解决方案(目前)。手动测试对API的请求时,一切都很好(我没有写测试,因为我是一个坏人),一切按预期进行,并且基本身份验证也很好。
我正在尝试解决使用纯文本用户名和密码登录的用户的流程,并将其发送到API进行身份验证,API只需说是或否,但来自站点(代表用户)的所有请求当他们想要POST / GET / PUT / DEL其中一种受保护的资源时,应使用其凭据对API进行签名。
在我读过的所有auth资源中,我仍然对使用哪种方案感到困惑。将纯文本密码存储在站点侧,以便我可以对它进行64位编码并通过网络发送它,这似乎很糟糕,但这似乎是我必须要做的。我已经阅读了摘要身份验证,但是我不确定我是否明白。任何和所有建议都欢迎。
这就是我处理这种情况的方式;
Authentication
标头,Bearer [JWT]
不必担心JWT,每种语言和框架都有很多实现,而且比您想象的要容易。甚至Google也已经有许多应用程序在使用JWT。
Auth0是一个身份验证代理,可以针对任何身份提供者或自定义数据库进行验证,并返回JWT。它提供了一个clientID(可用于对前端的配置文件进行解码)和一个密码(可用于验证后端中的令牌)以及用于执行此操作的客户端库。
免责声明:我为auth0工作。
更新:由于您提到了node.js并在注释中表示,因此我将举一个使用该技术的示例。
var http = require('http');
var express = require('express');
var jwt = require('jsonwebtoken'); //https://npmjs.org/package/node-jsonwebtoken
var expressJwt = require('express-jwt'); //https://npmjs.org/package/express-jwt
var secret = "this is the secret secret secret 12356";
var app = express();
app.configure(function () {
this.use(express.urlencoded());
this.use(express.json());
this.use('/api', expressJwt({secret: secret}));
});
//authentication endpoint
app.post('/authenticate', function (req, res) {
//validate req.body.username and req.body.password
//if is invalid, return 401
var profile = {
first_name: 'John',
last_name: 'Foo',
email: '[email protected]',
id: 123
};
var token = jwt.sign(profile, secret, {
expiresInMinutes: 60*5
});
res.json({
token: token
});
});
//protected api
app.get('/api/something', function (req, res) {
console.log('user ' + req.user.email + ' is calling /something');
res.json({
name: 'foo'
});
});
//sample page
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
http.createServer(app).listen(8080, function () {
console.log('listening on http://localhost:8080');
});
这是一个具有一个可验证用户名和密码的端点的快速应用程序。如果凭据有效,则它将返回具有完整配置文件的JWT令牌,有效期为5小时。
然后,在其中有一个示例端点,/api/something
但是由于我拥有用于其中所有内容的express-jwt中间件,/api
因此需要一个Authorization:Bearer标头和一个有效的令牌。中间件不仅验证令牌,还解析配置文件并将其放在req.user上。
如何使用此客户端?这是jquery的示例:
//this is used to parse the profile
function url_base64_decode(str) {
var output = str.replace("-", "+").replace("_", "/");
switch (output.length % 4) {
case 0:
break;
case 2:
output += "==";
break;
case 3:
output += "=";
break;
default:
throw "Illegal base64url string!";
}
return window.atob(output); //polifyll https://github.com/davidchambers/Base64.js
}
var token;
//authenticate at some point in your page
$(function () {
$.ajax({
url: '/authenticate',
type: 'POST',
data: {
username: 'john',
password: 'foo'
}
}).done(function (authResult) {
token = authResult.token;
var encoded = token.split('.')[1];
var profile = JSON.parse(url_base64_decode(encoded));
alert('Hello ' + profile.first_name + ' ' + profile.last_name);
});
});
//send the authorization header with token on every call to the api
$.ajaxSetup({
beforeSend: function(xhr) {
if (!token) return;
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
}
});
//api call
setTimeout(function () {
$.ajax({
url: '/api/something',
}).done(function (res) {
console.log(rest);
});
}, 5000);
首先,我使用用户名和密码进行了身份验证呼叫,可以在JWT中解码配置文件以获取用户配置文件,还保存令牌以供以后在每个请求中使用。
ajaxSetup / beforeSend技巧为每个调用添加标题。因此,然后我可以向/ api / something发出请求。
如您所见,这种方法不使用Cookie和会话,因此在CORS场景中开箱即用。
我是passport.js的忠实拥护者,并且为其他适配器提供了很多适配器和修复程序,但在这种情况下,我将不使用它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句