通过REST风格的呼叫声此登录逻辑? [英] Is this login logic via RESTful call sound?

查看:150
本文介绍了通过REST风格的呼叫声此登录逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我不是在谈论认证到的RESTful API调用。我说的是通过基于REST的API创建的用户登录逻辑。)

当用户访问我的网站,一个的任何页面Servlet过滤器将拦截请求,并检查是否有必要认证信息存在于会议。如果不存在,用户将被引导到登录页面。

在登录页面,Ajax调用是对用户名和密码的服务器一个RESTful API进行。取决于REST的API,返回状态,页面上的的JavaScript将决定是否让用户进入该网站。需要注意的是在服务器端的实际验证逻辑依然进行。客户端JS只作用的基础上,从服务器来的结果。

在服务器上,基于REST的API登录会检查提交的用户名/密码,看看它是否包含在数据库中。如果存在,它将存储必要认证信息会议从同一个客户端,以便将来的请求不会被阻止。

我的问题是:


  • 这是登录逻辑的声音?


  • 由于会议参与,REST风格的登录API是一种不无状态。因此,它仍然REST风格的?


下面是我的code:

login.js

  // login.js
$(函数(){
    $('#submitDiv')点击(doLogin);
});功能doLogin(){
    $('#resultDiv)文本(开始!)。
    用户=新的对象();
    user.username = $('#txtUsername)VAL()。
    user.pwd = $('#txtPassword)VAL()。    $阿贾克斯({
        标题:{
            接受:应用/ JSON,
            内容类型:应用/ JSON
        },
        类型:POST,
        URL:doLogin.sm',
        数据:JSON.stringify(用户)
        的dataType':'文字',
        '成功':loginSuccessful,
        完整的:功能(jqXHR,textStatus){
            $('#resultDiv)文本(完成:+ textStatus)。
        }
    });
}功能loginSuccessful(){
    //如果引用为null,则跳转到仪表板,否则跳转到引用。
    VAR引荐= getUrlVars()['引荐'];
    如果(引荐){
        window.location.replace(引荐);
    }
    其他{
        window.location.replace('dashboard.html');
    }
}

login.html的:

 <!DOCTYPE HTML>
< HTML LANG =ENGT&;
< HEAD>
    <标题>我云 - 登录网页< /标题>
    <链接rel =stylesheet属性类型=文/ CSS
          HREF =resources2 / CSS / bootstrap.css>
    <间的charset =UTF-8>
    <! - 武力使用最新的IE引擎 - >
    < META HTTP-EQUIV =X-UA-Compatible的内容=IE =边缘>
    < META NAME =视口CONTENT =WIDTH =设备宽度,初始规模= 1>
    <脚本SRC =resources2 / JS / jQuery的-1.11.3.js>< / SCRIPT>
    <脚本SRC =resources2 / JS / bootstrap.js>< / SCRIPT>
    <脚本SRC =resources2 / JS / pagejs / common.js>< / SCRIPT>
    <脚本SRC =resources2 / JS / pagejs / login.js>< / SCRIPT>
< /头>
<身体GT;
    < H1>我的登录页面和LT; / H1>
    < D​​IV ID =loginDiv>
        <输入ID =txtUsername类型=文本VALUE =测试>
        <输入ID =txtPasswordTYPE =密码值=测试>
        < D​​IV ID =submitDiv级=BTN BTN-默认>
            登录
        < / DIV>
        < D​​IV ID =resultDiv>< / DIV>
    < / DIV>
< /身体GT;
< / HTML>


解决方案

客户端(而不是服务器)上的会话状态

这就是罗伊·托马斯菲尔丁的其余教父的,在他的论文有关无国籍限制


  

5.1.3无状态


  
  

...]从客户机到服务器的每个请求必须包含所有的必要了解该请求中的信息,并且不能采取在服务器上所存储的上下文的优势。 会话状态,因此完全保存在客户端上。 [...]


所以,如果要保持在服务器上的会话状态的,它不休息。

在REST你不会在服务器上的会话,因此,的你不会有一个会话标识符

要处理必须包含所有数据的每个请求

从客户机到服务器的每个请求必须包含所有的必要的信息,由服务器来理解。有了它,你是不依赖于存储在服务器上的任何会话上下文。

当访问需要身份验证,例如,每个请求都必须包含对受保护资源的所有必要的数据,以正确进行身份验证/授权的。 这意味着认证将每个请求执行。

和验证数据应该属于标准的HTTP 授权 头。从 RFC 7235


  

4.2。授权


  
  

授权头域允许用户代理进行身份验证
  本身与原始服务器 - 通常是,但不一定是,后
  接收 401 (未授权)的回应。它的值由
  包含用户的认证信息凭证
  被请求代理资源的境界。 [...]


基本身份验证

基本身份验证方案,在 RFC 7617定义,是一个很好的启动确保一个REST API:


  

2。 基本认证方案


  
  

基本认证方案是基于该模型,客户端
  需要将自己与一个用户ID,并为每个密码进行身份验证
  保护空间(域)。 [...],服务器将服务该请求,只有当它可以验证
  申请到保护空间内的用户名和密码,
  请求的资源。


  
  

[...]


  
  

要获得授权,客户端


  
  

      
  1. 获得来自用户的用户名和密码,


  2.   
  3. 通过将用户ID构建用户通,单
      冒号(:)字符,密码,


  4.   
  5. 连接codeS用户传递到一个八位字节序列,


  6.   
  7. 和通过编码这个八进制序列,获得基本的凭据
      使用 的Base64编码成的 US-ASCII
      人物
    的。


  8.   

  
  

[...]


  
  

如果用户代理希望发送用户ID阿拉丁和密码
  芝麻开门,就可以使用下面的头字段:

 授权:基本QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

[...]


记住 HTTPS 是你最好的朋友,以prevent的的中间人攻击

令牌

如果您不想发送通过线路的用户名和密码为每一个请求,你可以考虑创建的基于令牌的认证的。在这种方法中,你这是在每个请求发送辅币硬盘凭据(用户名和密码)。

同样,必须为每个请求执行验证

基本上,令牌可以是<青霉>不透明的(其揭示了不超过该值本身以外的信息,例如一个的随机串的),或者可以是自包​​含的(比如 JSON网络令牌的)。


  • 随机字符串:令牌可以通过生成一个随机字符串,并坚持与到期日期和与之关联的用户标识符数据库发出


  • JSON网络令牌(JWT):由 RFC 7519定义,它是重新presenting索赔安全两方之间的一种标准方法。智威汤逊是一个自包含的令牌,使您能够存储用户标识符,到期日,不管你想(的但不存储密码的)的有效载荷,这是一个的 JSON EN $ C $光盘作为的 Base64编码。有效载荷可以由客户端读取和令牌的完整性可以通过在服务器上验证其签名容易地进行检查。你不会需要坚持JWT令牌,如果你不需要追踪他们。 Althought,通过持续的令牌,你将有无效和撤销他们的访问的可能性。为了找到一些重要的资源与智威汤逊的工作,看看 http://jwt.io


许多数据库在那里你可以坚持你的令牌。根据您的要求,您可以探索不同的解决方案,如关系数据库中,<一个HREF =htt​​p://db-engines.com/en/article/Key-value+Stores相对=nofollow>键值存储或的文档存储

(I am not talking about authenticating calls to RESTful API. I am talking about creating login logic for user via RESTful API.)

When user access any page of my site, a servlet filter will intercept the request and check if necessary authentication info exists in session. If not exists, user will be directed to login page.

On the login page, an ajax call is made to a RESTful API on server with username and password. Depending on the return status of that RESTful API, the JavaScript on the page will decide whether let user into the site. Note that the actual authentication logic is still carried out on server side. Client JS only acts based on the result from server.

On the server, the RESTful login API will check the submitted username/password and see if it is contained in DB. If exists, it will store necessary authentication info into the session so future requests from the same client will not be blocked.

My questions are:

  • Is this login logic sound?

  • Because session is involved, the RESTful login API is kind of not stateless. So is it still RESTful?

Here's my code:

login.js

// login.js
$(function () {
    $('#submitDiv').click(doLogin);
});

function doLogin() {
    $('#resultDiv').text("start!");
    user = new Object();
    user.username = $('#txtUsername').val();
    user.pwd = $('#txtPassword').val();

    $.ajax({
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        'type': 'POST',
        'url': 'doLogin.sm',
        'data': JSON.stringify(user),
        'dataType': 'text',
        'success': loginSuccessful,
        'complete': function (jqXHR, textStatus) {
            $('#resultDiv').text("complete with:" + textStatus);
        }
    });
}

function loginSuccessful() {
    //if referrer is null, jump to dashboard, else jump to referrer.
    var referer = getUrlVars()['referer'];
    if (referer) {
        window.location.replace(referer);
    }
    else {
        window.location.replace('dashboard.html');
    }
}

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>My Cloud - Login page</title>
    <link rel="stylesheet" type="text/css"
          href="resources2/css/bootstrap.css">
    <meta charset="utf-8">
    <!--force to use the latest IE engine-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="resources2/js/jquery-1.11.3.js"></script>
    <script src="resources2/js/bootstrap.js"></script>
    <script src="resources2/js/pagejs/common.js"></script>
    <script src="resources2/js/pagejs/login.js"></script>
</head>
<body>
    <h1>My Login Page</h1>
    <div id="loginDiv">
        <input id="txtUsername" type="text" value="test">
        <input id="txtPassword" type="password" value="test">
        <div id="submitDiv" class="btn btn-default">
            Login
        </div>
        <div id="resultDiv"></div>
    </div>
</body>
</html>

解决方案

Session state on the client (not on the server)

That's what Roy Thomas Fielding, The REST Godfather, said in his dissertation regarding the stateless constraint:

5.1.3 Stateless

[...] each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. [...]

So, if you are keeping the session state on the server, it's not REST.

In REST you won't have a session on the server and, consequently, you won't have a session identifier.

Each request must contain all data to be processed

Each request from client to server must contain all of the necessary information to be understood by the server. With it, you are not depending on any session context stored on the server.

When accessing protected resources that require authentication, for example, each request must contain all necessary data to be properly authenticated/authorized. It means the authentication will be performed for each request.

And authentication data should belong to the standard HTTP Authorization header. From the RFC 7235:

4.2. Authorization

The Authorization header field allows a user agent to authenticate itself with an origin server -- usually, but not necessarily, after receiving a 401 (Unauthorized) response. Its value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested. [...]

Basic authentication

The Basic Authentication Scheme, defined in the RFC 7617, is a good start for securing a REST API:

2. The 'Basic' Authentication Scheme

The Basic authentication scheme is based on the model that the client needs to authenticate itself with a user-id and a password for each protection space ("realm"). [...] The server will service the request only if it can validate the user-id and password for the protection space applying to the requested resource.

[...]

To receive authorization, the client

  1. obtains the user-id and password from the user,

  2. constructs the user-pass by concatenating the user-id, a single colon (":") character, and the password,

  3. encodes the user-pass into an octet sequence,

  4. and obtains the basic-credentials by encoding this octet sequence using Base64 into a sequence of US-ASCII characters.

[...]

If the user agent wishes to send the user-id "Aladdin" and password "open sesame", it would use the following header field:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

[...]

Remember the HTTPS is your best friend to prevent the man-in-the-middle attack.

Tokens

If you don't want sending the username and the password over the wire for every request, you can consider creating a token based authentication. In this approach, you exchange your hard credentials (username and password) for a token which is sent in each request.

Again, the authentication must be performed for every request.

Basically, the token can be opaque (which reveals no details other than the value itself, like a random string) or can be self-contained (like JSON Web Token).

  • Random String: A token can be issued by generating a random string and persisting it to a database with an expiration date and with a user identifier associated to it.

  • JSON Web Token (JWT): Defined by the RFC 7519, it's a standard method for representing claims securely between two parties. JWT is a self-contained token and enables you to store a user identifier, an expiration date and whatever you want (but don't store passwords) in a payload, which is a JSON encoded as Base64. The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To find some great resources to work with JWT, have a look at http://jwt.io.

There are many databases where you can persist your tokens. Depending on your requirements, you can explore different solutions such as relational databases, key-value stores or document stores.

这篇关于通过REST风格的呼叫声此登录逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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