一个网站和自有API之间验证 [英] Auth between a website and self-owned API

查看:139
本文介绍了一个网站和自有API之间验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能已经问过,所以从我preemptive道歉。

This has probably been asked before, so a preemptive apology from me.

我建了一个网站,我建立了一个API。该API也将在未来的移动应用使用。我自己都这样,我pretty确保二和三足式OAuth是不适合我。 API有那些对世界和其它部件被保护可访问并要求用户帐户份。为了简单起见,我刚刚去了HTTPS +基本身份验证解决方案(现在)。手动测试请求时的API(因为我是个坏人我没写测试),工作的事情如预期这一切都很好,好,基本验证是好的。

I built a site and I built an API. The API will also be used by a mobile app in the future. I own both so I'm pretty sure two and three legged OAuth aren't for me. The API has parts that are accessible to the world and other parts that are protected and require a user account. To keep things simple I've just gone with a https + Basic Auth solution (for now). It's all fine and good when testing requests manually to the API (I didn't write tests because I'm a bad person), things work as expected and Basic Auth is fine.

我试图来解决用户登录的与明文用户名和密码的流程,发送到API来进行身份验证,API只需说是或不是,从网站但所有请求(代表用户)的API应该以某种方式与他们的凭据签订当他们想POST / GET / PUT /受保护资源的DEL之一。

I'm trying to solve the flow of a user logging in with plaintext user and password, send that to the API to authenticate, the API just needs to say yes or no, yet all requests from the site (on behalf of a user) to the API should be signed in some way with their credentials for when they want to POST/GET/PUT/DEL one of the protected resources.

在所有我读过的权威性资源的我仍然困惑,使用什么方案。储存在现场侧明文密码,这样我可以基地64 EN code,并通过线路似乎不好发送,但看起来这就是我要做的。我读过消化权威性的,但我不知道我得到它。任何及所有的建议是值得欢迎的。

Out of all of the auth resources I've read I'm still confused as to what scheme to use. Storing the plaintext password on the site side so that I can base 64 encode it and send it over the wire seems bad, but it looks like that's what I'd have to do. I've read of digest auth but I'm not sure I get it. Any and all advice is welcome.

推荐答案

这是我将如何处理这种情况;

This is how I would handle this case;


  1. 张贴的用户名和密码为纯文本使用,当然你的HTTPS的API。

  2. 然后验证它到你的数据库,采用了时下盐密码最好的算法 bcrypt

  3. 如果用户不是有效的返回401,或什么的。

  4. 如果用户是有效的,返回JWT令牌与公钥算法签上了自己的个人资料。

  5. 您弗朗高端知道公共密钥,因此它可以去code中的智威汤逊,但它不能产生一个新的。

  6. 对于每个需要身份验证,则附加一个验证头,用承载[智威汤逊]
  7. 在后端中间件读取此标头和私钥进行验证。

不要affraid智威汤逊中有大量的每一种语言和框架的实现,是比你想象的更容易。很多应用程序已经在使用智威汤逊已连谷歌。

Don't be affraid of JWT there are plenty of implementations for every language and framework and is easier than you might think. A lot of applications are already using JWT already even Google.

Auth0 是一个身份验证代理可以验证对任何身份提供或定制的数据库,并返回JWTs。它提供了可用于脱code在前端的轮廓和秘密来验证在后端的标记以及客户端库来做到这一点。

Auth0 is an authentication broker that can validate against any identity provider or custom database, and returns JWTs. It provides a clientID that can be used to decode the profile in the front end and a secret to validate the tokens in the backend as well as client side library to do this.

免责声明:我的工作auth0

更新:既然你提到的评论的Node.js和前preSS我会以这种技术的例子

Update: Since you mention node.js and express in comments I will give an example in this technology.

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: 'foo@bar.com',
    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');
});

这是一个验证的用户名和密码,一个端点的前preSS应用。如果凭据有效返回一个JWT令牌的完整资料,用过期5小时。

This is an express application with one endpoint that validates username and password. If the credentials are valid it returns a JWT token with the full profile, with expiration 5 hours.

然后,我们有一个例子端点 / API /东西,但因为我已经为一切EX preSS-智威汤逊中间件上 / API 它需要一个授权:承载头一个有效的令牌。不仅中间件验证令牌还会解析配置文件并把它放在req.user。

Then we have an example endpoint in /api/something but since I've a express-jwt middleware for everything on /api it requires a Authorization: Bearer header with a valid token. The middleware not only validates the token but also parses the profile and put it on req.user.

如何使用客户端?这是使用jQuery的例子:

How to use this client-side? This is an example with 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);

首先,我已经与用户名和密码身份验证一个电话,我可以去code。在智威汤逊的配置文件,以获取用户个人资料,我还保存在以后的每个请求使用该令牌。

First, I've an authenticate call with the username and password, I can decode the profile in the JWT to get the user profile and I also save the token to use in every request later on.

该ajaxSetup / beforeSend招增加了对每一个电话的报头。所以,那么我可以做出/ API /东西的请求。

The ajaxSetup/beforeSend trick adds the header for every call. So, then I can make a request to /api/something.

你可以想象这种方法不使用cookie和session所以它的作品出CORS方案的开箱。

As you can imagine this approach doesn't use cookies and sessions so it works out of the box in CORS scenarios.

我passport.js的忠实粉丝,我已经做出了很大贡献适配器和修复一些其他适配器,但对于这种特殊情况下,我不会使用它。

I'm a big fan of passport.js and I've contributed a lot of adapters and fixes for some other adapter but for this particular case I wouldn't use it.

这篇关于一个网站和自有API之间验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆