Bootstrap

登陆用户身份获取

一 基于 Token 的身份验证方法

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。主要的流程如下:

JWT(JSON WEB TOKEN)就是基于Token的一种框架。根据描述,可以理解如下:

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准.该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

RFC7519文档原文:

          JSON Web Token (JWT)

Abstract

   JSON Web Token (JWT) is a compact, URL-safe means of representing
   claims to be transferred between two parties.  The claims in a JWT
   are encoded as a JSON object that is used as the payload of a JSON
   Web Signature (JWS) structure or as the plaintext of a JSON Web
   Encryption (JWE) structure, enabling the claims to be digitally
   signed or integrity protected with a Message Authentication Code
   (MAC) and/or encrypted.

Status of This Memo

   This is an Internet Standards Track document.

   This document is a product of the Internet Engineering Task Force
   (IETF).  It represents the consensus of the IETF community.  It has
   received public review and has been approved for publication by the
   Internet Engineering Steering Group (IESG).  Further information on
   Internet Standards is available in Section 2 of RFC 5741.

   Information about the current status of this document, any errata,
   and how to provide feedback on it may be obtained at
   http://www.rfc-editor.org/info/rfc7519.

二 登陆流程与获取方式

我们的登陆步骤与常规的授权中心-权限验证方式没有区别。

接口内用户登陆信息获取:

WebAppConfig中配置拦截器 AuthUserInterceptor,是通过拦截器从请求的request中,header部分提取用户的登陆信息(key为 user),并注入到AuthenUser对象中。

在接口中,直接使用参数AuthenUser即可获取用户登陆信息。

属性如下:

AuthenUser

{
    "code": 0,
    "msg": "成功",
    "data": {
        "user": {
            "id": 1,
            "userName": "admin",
            "authStatus": 1,
            "role": 1,
            "email": "admin@qingclass.com",
            "phone": "17196699712",
            "createTime": "2018-07-31 16:27:50",
            "modifyTime": "2018-08-06 10:18:01"
        }
    }
}

AuthUserInterceptor的核心代码:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String user = request.getHeader("user");
        if (user != null && !StringUtils.isEmpty(user)) {
            request.setAttribute(AuthenUser.class.getName(), JSON.parseObject(URLDecoder.decode(user, "utf-8"), AuthenUser.class));
            return true;
        } else {
            return this.print(request, response, ResponseCode.NEED_LOGIN);
        }
    }

三 扩展-session认证

3.1 传统的session认证

http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据http协议,我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于session认证。

但是这种基于session的认证使应用本身很难得到扩展,随着不同客户端用户的增加,独立的服务器已无法承载更多的用户,而这时候基于session认证应用的问题就会暴露出来.

3.2 基于session认证所显露的问题

Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。