权限认证基础:区分Authentication,Authorization以及Cookie、Session、Token

2023-05-16

1. 认证 (Authentication) 和授权 (Authorization)的区别是什么?

这是一个绝大多数人都会混淆的问题。首先先从读音上来认识这两个名词,很多人都会把它俩的读音搞混,所以我建议你先先去查一查这两个单词到底该怎么读,他们的具体含义是什么。

说简单点就是:

  • 认证 (Authentication): 你是谁。
  • 授权 (Authorization): 你有权限干什么。

稍微正式点(啰嗦点)的说法就是:

  • Authentication(认证) 是验证您的身份的凭据(例如用户名/用户ID和密码),通过这个凭据,系统得以知道你就是你,也就是说系统存在你这个用户。所以,Authentication 被称为身份/用户验证。
  • Authorization(授权) 发生在 Authentication(认证) 之后。授权嘛,光看意思大家应该就明白,它主要掌管我们访问系统的权限。比如有些特定资源只能具有特定权限的人才能访问比如admin,有些对系统资源操作比如删除、添加、更新只能特定人才具有。

这两个一般在我们的系统中被结合在一起使用,目的就是为了保护我们系统的安全性。

2. 什么是Cookie ? Cookie的作用是什么?如何在服务端使用 Cookie ?

2.1 什么是Cookie ? Cookie的作用是什么?

Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。

维基百科是这样定义 Cookie 的:Cookies是某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。简单来说: Cookie 存放在客户端,一般用来保存用户信息。

下面是 Cookie 的一些应用案例:

  1. 我们在 Cookie 中保存已经登录过的用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了。除此之外,Cookie 还能保存用户首选项,主题和其他设置信息。
  2. 使用Cookie 保存 session 或者 token ,向后端发送请求的时候带上 Cookie,这样后端就能取到session或者token了。这样就能记录用户当前的状态了,因为 HTTP 协议是无状态的。
  3. Cookie 还可以用来记录和分析用户行为。举个简单的例子你在网上购物的时候,因为HTTP协议是没有状态的,如果服务器想要获取你在某个页面的停留状态或者看了哪些商品,一种常用的实现方式就是将这些信息存放在Cookie

2.2 如何能在 服务端使用 Cookie 呢?

这部分内容参考:https://attacomsian.com/blog/cookies-spring-boot,更多如何在Spring Boot中使用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";
}

3. Cookie 和 Session 有什么区别?如何使用Session进行身份验证?

Session 的主要作用就是通过服务端记录用户的状态。 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。

Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。相对来说 Session 安全性更高。如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。

那么,如何使用Session进行身份验证?

很多时候我们都是通过 SessionID 来实现特定的用户,SessionID 一般会选择存放在 Redis 中。举个例子:用户成功登陆系统,然后返回给客户端具有 SessionID 的 Cookie,当用户向后端发起请求的时候会把 SessionID 带上,这样后端就知道你的身份状态了。关于这种认证方式更详细的过程如下:

Session Based Authentication flow

  1. 用户向服务器发送用户名和密码用于登陆系统。
  2. 服务器验证通过后,服务器为用户创建一个 Session,并将 Session信息存储 起来。
  3. 服务器向用户返回一个 SessionID,写入用户的 Cookie。
  4. 当用户保持登录状态时,Cookie 将与每个后续请求一起被发送出去。
  5. 服务器可以将存储在 Cookie 上的 Session ID 与存储在内存中或者数据库中的 Session 信息进行比较,以验证用户的身份,返回给用户客户端响应信息的时候会附带用户当前的状态。

另外,Spring Session提供了一种跨多个应用程序或实例管理用户会话信息的机制。如果想详细了解可以查看下面几篇很不错的文章:

  • Getting Started with Spring Session
  • Guide to Spring Session

4. 什么是 Token?什么是 JWT?如何基于Token进行身份验证?

我们在上一个问题中探讨了使用 Session 来鉴别用户的身份,并且给出了几个 Spring Session 的案例分享。 我们知道 Session 信息需要保存一份在服务器端。这种方式会带来一些麻烦,比如需要我们保证保存 Session 信息服务器的可用性、不适合移动端(依赖Cookie)等等。

有没有一种不需要自己存放 Session 信息就能实现身份验证的方式呢?使用 Token 即可!JWT (JSON Web Token) 就是这种方式的实现,通过这种方式服务器端就不需要保存 Session 数据了,只用在客户端保存服务端返回给客户的 Token 就可以了,扩展性得到提升。

JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的,因此接收者便可以验证它的真实性。

下面是 RFC 7519 对 JWT 做的较为正式的定义。

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. ——JSON Web Token (JWT)

JWT 由 3 部分构成:

  1. Header :描述 JWT 的元数据。定义了生成签名的算法以及 Token 的类型。
  2. Payload(负载):用来存放实际需要传递的数据
  3. Signature(签名):服务器通过PayloadHeader和一个密钥(secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

在基于 Token 进行身份验证的的应用程序中,服务器通过PayloadHeader和一个密钥(secret)创建令牌(Token)并将 Token 发送给客户端,客户端将 Token 保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization字段中: Authorization: Bearer Token

Token Based Authentication flow

  1. 用户向服务器发送用户名和密码用于登陆系统。
  2. 身份验证服务响应并返回了签名的 JWT,上面包含了用户是谁的内容。
  3. 用户以后每次向后端发请求都在Header中带上 JWT。
  4. 服务端检查 JWT 并从中获取用户相关信息。

 

5 什么是OAuth 2.0?

OAuth 是一个行业的标准授权协议,主要用来授权第三方应用获取有限的权限。而 OAuth 2.0是对 OAuth 1.0 的完全重新设计,OAuth 2.0更快,更容易实现,OAuth 1.0 已经被废弃。详情请见:rfc6749。

实际上它就是一种授权机制,它的最终目的是为第三方应用颁发一个有时效性的令牌 token,使得第三方应用能够通过该令牌获取相关的资源。

OAuth 2.0 比较常用的场景就是第三方登录,当你的网站接入了第三方登录的时候一般就是使用的 OAuth 2.0 协议。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

权限认证基础:区分Authentication,Authorization以及Cookie、Session、Token 的相关文章

  • 身份验证后以编程方式添加角色

    我有以下 JSF 2 1 登录表单 在 Glassfish 3 1 中运行
  • NHibernate Session.Flush & Evict 与 Clear

    在一个测试中 我想要持久化一个对象 然后通过从数据库 而不是会话 获取它来证明它是持久化的 我注意到以下内容没有区别 save it session Clear fetch it or save it session Flush sessi
  • 使用 SenchaTouch 的简单登录表单

    刚开始研究 SenchaTouch 这看起来很有前途 我正在构建我的第一个应用程序 一个简单的登录表单检查源http pastebin com 8Zddr9cj http pastebin com 8Zddr9cj 我正在寻找一种方法来执行
  • 如何在 GWT 中实现登录屏幕?

    我正在为后端应用程序编写一个小型 GWT 前端 我想知道 GWT 应用程序的最佳安全模型是什么 我正在考虑实现一种 RPC 方法 该方法从客户端网页接收用户密码的 MD5 然后将会话 ID 传回客户端页面 或失败代码 所有后续调用都将简单地
  • 会话在选项卡之间共享

    我有 JAVA Web 应用程序 我需要停止在浏览器选项卡之间共享会话 这意味着 用户打开浏览器 登录其帐户并在同一浏览器的新选项卡中打开特定页面 根据默认设置 会话将共享到新选项卡 并且用户会自动登录到新选项卡 谁能告诉我如何阻止这种情况
  • 使用字符串路径设置嵌套数组数据[重复]

    这个问题在这里已经有答案了 我正在尝试编写一个不寻常的用例 目标是这样的 我希望客户能够提供一个字符串 例如 cars honda civic On 使用这个字符串 我的代码将设置一个值 如下所示 data cars honda civic
  • PHP - 按后退按钮时 Session_Destroy

    这是我的问题 我有一个名为login php 的登录页面 不包含HTML 代码 当用户正确输入其凭据时 他会被重定向到特定页面 在本例中我们将使用 test php 该页面上的唯一链接会注销当前会话 并将用户返回到index html 我的
  • 新站点预计支持哪些知名 OpenID 提供商?

    我计划开发一个支持 OpenID Connect 作为依赖方的 Web 应用程序 以便该应用程序的用户可以使用他选择的身份提供商进行注册和登录 这与每个 Stack Exchange 站点上的 我的登录 使用的技术相同 该应用程序可供服务器
  • Rails 身份验证插件推荐

    我想向我的 Rails 应用程序添加身份验证 我遇到了几个这样做的插件 acts as authenticated restful authentication Authlogic 等 我还没有看到一篇文章描述使用每种方法的差异 优点和缺点
  • 我可以在 psycopg2 中使用 md5 身份验证吗?

    经过两个小时的阅读文档 源代码和帮助线程后 我放弃了 我无法让 psycopg2 使用 md5 字符串进行身份验证 根据this http bytes com topic python answers 42597 psycopg authe
  • 如何使用放心获取 Rest API 中的授权令牌?是否可以?

    目前使用 Postman 我必须向 API URL login 发送请求 并传递用户名和密码 作为回报 我得到令牌 如下所示 请求示例 login POST Body username admin password admin Return
  • 如何使用多重身份验证 - firebase?

    我有一个注册屏幕 其中包含 用户名 电子邮件 电话号码 密码 在本例中 我使用电话号码身份验证来验证号码 因此在用户验证他的号码后 我将他的数据保存到 firebase DB 中 所以在那之后 我将下摆导航到登录屏幕 应该包含电子邮件 密码
  • 同一域的子页面之间的 PHP 会话

    我有一个域 domain com 其中有多个子页面 这些子页面具有不同的会话 默认情况下 并且我希望其中一些子页面共享一个会话 例如我有domain com section1 staff and domain com section2 st
  • SharePoint Online 身份验证失败

    我有一个 C 应用程序 它通过使用 Web 请求对 SharePoint Online 进行身份验证 它对我来说非常有用 但其他人收到以下错误
  • 场次抽奖

    有人能解释一下什么是会话扫彩票吗 我已附加 Laravel 框架的默认会话配置文件 问题 1 它说某些会话驱动程序必须manually扫荡他们的 存储位置 有人可以描述这个过程以及为什么会这样吗 必要的 哪些会话驱动程序需要此操作 2 为什
  • ruby on Rails,会话过期通知

    我正在使用 ruby 1 9 3 和 Rails 3 2 我的实际会话处理如下所示 会话助手 def sign in user cookies remember token value user remember token expires
  • laravel 4 登录验证失败

    在 Laravel4 中 我在路由中编写了以下代码 但它总是将我重定向到登录页面 我用谷歌搜索并在堆栈溢出上找到了它 并尝试了所有解决方案但没有成功 我确信这将是一个愚蠢的错误 但请跟踪它 谢谢 Routes Route post logi
  • Django 的登录会话

    我正在尝试在我的网络应用程序中设置登录会话 但无法使其正常工作 我是 django 新手 阅读了会话文档 但没有连接到我的网络应用程序 我现在想要的只是检查用户是否已登录 如果没有则重定向到登录页面 这是我尝试合并登录会话的代码 设置 py
  • WebSphere 中跨 JVM 的会话复制

    我们建立了一个基础设施 其中网络服务器是集群的 而应用程序服务器不是 Web 服务器根据循环策略将请求路由到应用程序服务器 在这种情况下 一个应用程序服务器中可用的会话数据在另一应用程序服务器中不可用 无论如何 是否可以使来自第一个应用程序
  • 确定用于映射网络驱动器的域和用户名

    使用带有 SP1 的 Windows 7 Enterprise 但我希望得到适用于 Windows XP 2003 2008 Vista 7 的通用答案 从命令提示符处 我执行net use命令将 Z 驱动器映射到另一台计算机上的共享 但我

随机推荐