认证:用来验证用户身份,比如说用户名或用户ID/密码这些
授权:发生在认证之后,赋予用户某个功能或访问权限
一般在系统中这两者会被结合使用,为了确保系统的安全性
1、系统权限控制最常采用的访问控制模型就是RBAC模型
RBAC是基于角色的权限访问控制,这是一种通过角色关联权限,角色又同时关联用户的授权方式。(简单地说就是,一个用户可以拥有多个角色,一个角色可以被分配多个权限,这样就构成了“用户--角色--权限”的授权模式,在这种模型中,用户与角色,角色与权限之间构成了多对多的关系。通常来说,如果系统对于权限控制要求严格的话,一般都会选择RBAC模型来做权限控制)。
2、Cookie和Session的用途
Cookie和Session都是用来跟踪浏览器用户身份的会话方式,但两者的应用场景不太一样。
Cookie的作用?
简单来说:Cookie存放在客户端,一般用来保存用户信息(某些网站为了辨别用户身份而存储在用户本地终端上的数据(通常经过加密))
Cookie的应用案例:
1、我们在Cookie中保存已经登录过的用户信息,下次访问网站的时候页面可以自动帮你登录一些基本信息,除此之外,Cookie还能保存用户首选项,主题和其他设置信息。
2、使用Cookie保存SessionId或者Token,向后端发送请求的时候带上Cookie,这样后端就能收到SessionId或者Token了,这样就能记录用户当前的状态了,因为HTTP协议是无状态的。
3、Cookie还可以用来记录和分析用户行为,举个简单的例子,当你在上网购物的时候,因为HTTP协议是没有状态的,如果服务器想要获取你在某个页面的停留状态或者看了哪些商品,一种常见的方式就是将这些信息存放在Cookie中。
Cookie在项目中的应用?
1)设置
Cookie
返回给客户端@GetMapping("/change-username") public String setCookie(HttpServletResponse response) { // 创建一个 cookie Cookie cookie = new Cookie("username", "Jovan"); //设置 cookie过期时间 cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days //添加到 response 中 response.addCookie(cookie); return "Username is changed!"; }
2) 使用 Spring 框架提供的
@CookieValue
注解获取特定的 cookie 的值@GetMapping("/") public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") String username) { return "Hey! My username is " + username; }
3) 读取所有的
Cookie
值@GetMapping("/all-cookies") public String readAllCookies(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); if (cookies != null) { return Arrays.stream(cookies) .map(c -> c.getName() + "=" + c.getValue()).collect(Collectors.joining(", ")); } return "No cookies"; }
Session的作用?
Session的主要作用就是通过服务端记录用户状态。典型的应用场景就是,当你添加商品到购物车,系统不知道哪个用户操作的,因为HTTP协议是无状态的,服务端给特定的用户创建特定的Session之后就可以标识这个用户并且跟踪这个用户了。
3、 Session和Cookie的区别?
Cookie数据保存在客户端(浏览器端),Session数据保存在服务器端,相对来说Session安全性更高,如果使用Cookie,一些敏感信息就不要写入Cookie中,最好能将Cookie信息加密后使用,到时候再去服务器端解密。
4、如何使用Session-Cookie方案进行身份验证?
一般情况我们都是通过SessionID来实现特定用户,SessionID一般会选择存放在Redis中,举个例子:
1、当用户登录成功,服务端会给客户端返回一个带有SessionId的Cookie
2、当用户端再次向服务端发起请求的时候,会携带SessionId的Cookie过去,这样后端就知道登录者的身份状态了。
更详细的过程如下:
1、用户向服务端发送用户名、密码、验证码用于登录系统
2、服务器验证通过后,会为用户创建一个Session,并将Session信息存起来
3、服务器向用户返回一个SessionID,写入用户的Cookie
4、当用户保持登录状态时,Cookie上的SessionID与存储在内存中或者数据库中的Session信息进行比较,来验证用户的身份,返回给客户端响应信息的时候会附带用户的当前状态。
使用Session要注意:
依赖Session的关键业务一定要确保客户端开启了Cookie
注意Session的过期时间
5、多服务器节点下的Session-Cookie方案如何实现?
Session-Cookie方案在单体环境中是一个很好的身份认证方案,但是,当服务器水平拓展到多个节点时,该方案就要面临挑战了。举个例子:假设我们部署了两份相同的服务器A和B,用户第一次登录的时候,Nginx通过负载均衡机制将用户请求转发到A服务器,此时用户的Session信息保存到A服务器,结果,用户第二次登录,Nginx将用户的请求路由到B服务器,而B服务器没有存储用户的Session信息,此时用户需要重新登录。
我们应该如何避免上面这种情况的出现呢?
有几个方案可供大家参考:
- 某个用户的所有请求都通过特性的哈希策略分配给同一个服务器处理。这样的话,每个服务器都保存了一部分用户的 Session 信息。服务器宕机,其保存的所有 Session 信息就完全丢失了。
- 每一个服务器保存的 Session 信息都是互相同步的,也就是说每一个服务器都保存了全量的 Session 信息。每当一个服务器的 Session 信息发生变化,我们就将其同步到其他服务器。这种方案成本太大,并且,节点越多时,同步成本也越高。
- 单独使用一个所有服务器都能访问到的数据节点(比如缓存)来存放 Session 信息。为了保证高可用,数据节点尽量要避免是单点。
- Spring Session 是一个用于在多个服务器之间管理会话的项目。它可以与多种后端存储(如 Redis、MongoDB 等)集成,从而实现分布式会话管理。通过 Spring Session,可以将会话数据存储在共享的外部存储中,以实现跨服务器的会话同步和共享