详解 http 鉴权

article/2025/9/19 7:25:55

详解 http 鉴权

【总结分享】10种常用前后端鉴权方法,让你不再迷惘 🌟🌟🌟

前端开发登录鉴权方案完全梳理 🌟🌟🌟

实践出真知,聊聊 HTTP 鉴权那些事

注:此处主要讲的是 http 鉴权涉及 API 鉴权,主要场景是将接口提供给前端或第三方使用时需要鉴权,而非用户登录系统。通常在当前流行的微服务中,主要在 gateway 层做相关认证,下游链路是默认开放的。

概念明确:

  • 认证 Identification:根据声明者所持有的识别信息,确认声明者的身份
  • 授权 Authorization:在信息安全领域是指资源所有者委派执行者,赋予执行者指定范围的资源操作权限,以便对资源的相关操作。
  • 鉴权 Authentication:在信息安全领域是指对于一个声明者所声明的身份权利,对其所声明的真实性进行鉴别确认的过程。
  • 权限控制 Access/Permission Control:将操作制成权限列表,然后判断操作允许或禁止

通常四者的关系是:认证 --> 授权 --> 鉴权 --> 权限控制

在不涉及权限控制的系统中,一般到鉴权这一步就能拿到数据。

下面讲集中常用的鉴权方式:

Basic auth

在 header 头中加入 ‘Authorization: Basic dXNlcjE6MTIzNDU2’,其中 dXNlcjE6MTIzNDU2 是 user1:123456 base64 编码之后的结果, 其为用户名密码,这种方式非常简单且极易被破解,仅做了解。

使用方式

// header 
Authorization: Basic dXNlcjE6MTIzNDU2

Session-cookie

概念

cookie: 服务端下发给浏览器端的数据,浏览器每次发送请求都会携带这段数据

  • cookie 存储在客户端,可随意篡改,不安全
  • 有大小限制,最大为 4kb
  • 有数量限制,一般一个浏览器对于一个网站只能存不超过 20 个 Cookie,浏览器一般只允许存放 300 个 Cookie
  • Cookie 是不可跨域的,但是一级域名和二级域名是允许共享使用的(靠的是 domain)

session: 服务端保存生成的 session 信息,客户端在收到 session 信息后会在下次请求时带上 session_id,服务端查找到对应的会话信息来持续之前断掉的会话,cookie 和 session 都弥补了 http 是个无状态协议这一特点。与 cookie 的区别如下:

  • 安全性: Cookie 由于保存在客户端,可随意篡改,Session 则不同存储在服务器端,无法伪造,所以 Session 的安全性更高;
  • 存取值的类型不同: Cookie 只支持字符串数据,Session 可以存任意数据类型;
  • 有效期不同: Cookie 可设置为长时间保持,Session 一般失效时间较短;
  • 存储大小不同: Cookie 保存的数据不能超过 4K;

时序图

使用 session-cookie 鉴权的时序图如下:

image

  1. 客户端首次访问(登录),服务端自动创建 session 保存在 redis 或者内存中
  2. 可以对 sid(session id) 进行加密
  3. 浏览器解析响应头将 sid 存在 cookie 中,之后的访问都带着它,服务端根据它来鉴权
  4. 用户登出,客户端和服务端均销毁各自保存的 session id

优势:

  • Cookie 简单易用可以在客户端长时间保存
  • Session 数据存储在服务端,相较于 JWT 方便进行管理,也就是当用户登录和主动注销,只需要添加删除对应的 Session 就可以了,方便管理

缺点:

  • 不安全,Cookie 将数据暴露在浏览器中,增加了数据被盗的风险(容易被 CSRF 等攻击)
  • Session 存储在服务端,增大了服务端的开销,用户量大的时候会大大降低服务器性能
  • 分布式系统中为了保存 session 需要启用一个 Redis 集群,成本较高

使用方式

// header 
cookie: sessionid=123456

使用场景

  • 一般中大型的网站都适用(除了 APP 移动端);
  • 由于一般的 Session 需集中存储在内存服务器上(如 Redis),这样就会增加服务器的预算,所以预算不够请谨慎选择

token

时序图

使用 token 鉴权的时序图

image

和 session-cookie 的区别在于:token 是 session-cookie 的升级版

  • token 在服务端不存库,每次通过定义的规则校验是否匹配合法即可
  • token 在客户端存在 localStorage 或 sessionStorage 中,因此不受限于 cookie 的缺点,比如大小受限、native app 不能使用 cookie、浏览器中 cookie 存储功能被禁用、跨域影响等
  • 客户端再发请求时直接放在头部 Authorization 字段中发送
  • 更灵活比如 JWT 等

优点:

  • 服务端无状态,token 不必再存储在服务端
  • 支持移动设备,支持跨域,有效避免 csrf 攻击因为不需要用 cookie。但是会存在 XSS 攻击中被盗的风险,但是可选择 Token 存储在标记为 httpOnly 的 Cookie 中,能够有效避免浏览器中的 JS 脚本对 Cookie 的修改

缺点:

  • 占带宽:正常情况下比 sid 更大,消耗更多流量,挤占更多宽带
  • 性能问题:相比较于 Session-Cookie 认证来说,Token 需要服务端花费更多时间和性能来对 Token 进行解密验证,其实 Token 相较于 Session—Cookie 来说就是一个时间换空间的方案
  • 有效期问题:为了避免 Token 被盗用,一般 Token 的有效期会设置的较短,所以就有了 Refresh Token;

refresh token

概念

refresh token 的概念和 access token 密切相关

Access Token: 用来访问业务接口,由于有效期足够短,盗用风险小,也可以使请求方式更宽松灵活;

Refresh Token: 用来获取 Access Token,有效期可以长一些,通过独立服务和严格的请求方式增加安全性;由于不常验证,也可以如前面的 Session 一样处理;一般如果 refresh Token 也过期了则需要重新登录。

JWT json web token

概念

对 JSON 进行加密签名来实现授权验证的方案

组成

  • header 头部
    • typ token 类型
    • alg 使用的 hash 算法,通常是 hmac sha256 或 rsa
{"alg": "HS256","typ": "JWT"
}
  • Payload: claim 即通常包含 user 信息以及实际需要传递的数据,官方定义了如下七个字段供使用,但也可以自己加私有字段

    • iss (issuer):签发人
    • exp (expiration time):过期时间
    • sub (subject):主题
    • aud (audience):受众
    • nbf (Not Before):生效时间
    • iat (Issued At):签发时间
    • jti (JWT ID):编号
    {"iss": "Jehoshaphat Tse","iat": 1441593502,"exp": 1441594722,"aud": "www.example.com","sub": "mrsingsing@example.com","name": "John Doe","admin": true
    }
    
  • signature 签名,对前面两部分进行签名,防止数据被篡改

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

其中 secret 是一个密钥,只有服务器知道,不会泄露给用户,使用的签名算法是 header 中指定的,默认即 HMAC SHA256

优势:

  • 不需要在服务端保存会话信息,所以易于应用的扩展
  • JWT 中的 Payload 负载可以存储常用信息,用于信息交换,有效地使用 JWT,可以降低服务端查询数据库的次数

缺点:

  • 时效问题:由于服务端不存储状态,所以一旦 jwt 签发了就不能在使用过程中废止。
  • 安全性:由于 jwt 的 payload 是 base64 编码的没有进行加密,所以不能存储敏感数据但也可以通过加密来解决这个问题
  • 性能问题:jwt 放在 header 中,占用空间大导致 header 可能比 body 还大

时序图
image

使用方式

// header
Authorization: Bearer <token>

通常将 jwt 存储在 localStorage 中

使用场景

不需要服务端保存用户状态的场景。但通常如果考虑到 token 注销的场景的话,没有特别好的解决方案,大部分解决方案是给 token 加状态,比如为每个用户创建专属 secret 有点类似于 session-cookie 认证了,对于续签的问题可以通过每次请求都返回新的 token 的方式或即将过期的时候服务端即重新颁发新的给客户端。

总结 jwt 的做法其实我们可以借鉴做一下 jwt 的变形,比如 header 中使用如下验证方式:

// header
// ts 用于校验时间
// sign 用于保证数据不被篡改
// 发送给服务端后对比签名是否一样(需要客户端和服务端都知道密钥才能按相同的算法生成签名)
timestamp+signature(secret, payload)

SSO single sign-on

概念

多系统应用群中登录单个系统即可在其他系统中获得授权无需再次登录其他系统即可使用。

同域 SSO

当存在两个相同域名下的系统 A a.abc.com 和系统 B b.abc.com 时,以下为他们实现 SSO 的步骤:

  1. 用户访问某个子系统时(例如 a.abc.com),如果没有登录,则跳转至 SSO 认证中心提供的登录页面进行登录
  2. 登录认证后,服务端把登录用户的信息存储于 Session 中,并生成会话身份凭证追加在响应头的 set-cookie字段中,随着请求返回写入浏览器中。
  3. 下次发送请求时,当用户访问同域名的系统 B 时,由于 A 和 B 在相同域名下,也是 abc.com,浏览器会自动带上之前的 Cookie。此时服务端就可以通过该 Cookie 来验证登录状态了,注意防 xss 需要设置 cookie 为 http-only。

这实际上使用的就是 Session-Cookie 认证的登录方式。

跨域 SSO

由于跨域,cookie 不能共享了,比如我们登录了 taobao.com 希望同时能登上 tmall.com

saml 协议

Authing saml intro 🌟🌟

SAML Web SSO学习 🌟🌟🌟

概念

saml security assertion markup language: 安全断言标记语言

SP service provider:服务提供方,如阿里云控制台、aws 控制台等

IdP identity provider: 身份提供方,能够向 SP 发送身份断言,即标识某个人身份的 token,且在 saml 协议中其为 xml 形式

通常 SP 和 IdP 互相存着对方的 MetaData

组成

image

  1. assertions 断言:包含 authentication、attribute、entitlement information
  2. protocols 协议
  3. bindings
  4. profiles
  5. MetaData
    1. IdP 发出 saml response 之前会在 MetaData 中查询受信 sp 列表,并发向其定义的 endpoint
    2. SP 根据 IdP MetaData 里的公钥验证断言上的签名
    3. SP 从 MetaData 查找 IdP 的组件服务的预先安排的 endpoint

时序图

image

OAuth2.0

  • TODO 待补充

ak sk

常用于云服务中

AK/SK(aksk)鉴权原理简介

简介

AK: Access Key Id,用于标示用户;
SK: Secret Access Key,是用户用于加密认证字符串和服务端用来验证该字符串的密钥,因此 SK 必须保密;

综上 aksk 其实是通过使用 Access Key Id / Secret Access Key 加密的方法来验证某个请求的发送者身份。

使用流程

判断用户请求中是否包含 Authorization 认证字符串。如果包含认证字符串,则执行下一步操作。
基于HTTP请求信息,使用相同的算法,生成Signature字符串。
使用服务器生成的Signature字符串与用户提供的字符串进行比对,如果内容不一致,则认为认证失败,拒绝该请求;如果内容一致,则表示认证成功,系统将按照用户的请求内容进行操作。

客户端:

1. 构建http请求(包含 access key);

2. 使用请求内容和 secret access key 计算的签名(signature);

3. 发送请求到服务端;

服务端:

1. 根据发送的 access key 查找数据库得到对应的 secret-key;

2. 使用同样的算法将请求内容和 secret-key 一起计算签名(signature),与客户端步骤2相同;

3. 对比用户发送的签名和服务端计算的签名,两者相同则认证通过,否则失败。


http://chatgpt.dhexx.cn/article/CrvMGt0V.shtml

相关文章

文件服务器鉴权,服务鉴权

使用kmse实现服务的权限校验 通过一个简单的实例说明开发者如何通过kmse进行服务间的权限校验。 一、准备客户端和服务端两个demo 这里演示如何快速实践服务鉴权功能。假如现在有两个微服务 auth-client 和 auth-server&#xff0c;想实现 auth-client 调用 auth-server 时&…

前后端常见的几种鉴权方式

最近在重构公司以前产品的前端代码,摈弃了以前的session-cookie鉴权方式,采用token鉴权,忙里偷闲觉得有必要对几种常见的鉴权方式整理一下。 目前我们常用的鉴权有四种: HTTP Basic Authenticationsession-cookieToken 验证OAuth(开放授权)一.HTTP Basic Authentication 这…

鉴权的4种基本方法

一、基于服务器常出现的问题 Seesions&#xff1a; 每次认证用户发起请求时&#xff0c;服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时&#xff0c;内存的开销也会不断增加。 可扩展性&#xff1a; 由于sessions存放在服务器内存中&#xff0c;伴随而来的是可…

什么是鉴权?一篇文章带你了解postman的多种方式

目录 一、什么是鉴权&#xff1f; 二、postman鉴权方式 一、什么是鉴权&#xff1f; 鉴权也就是身份认证&#xff0c;就是验证您是否有权限从服务器访问或操作相关数据。发送请求时&#xff0c;通常必须包含相应的检验参数以确保请求具有访问权限并返回所需数据。通俗的讲就…

10 分钟带你了解鉴权那些事

前言&#xff1a; 鉴权是自动化测试路上的拦路虎&#xff0c;相信大部分同学都深有体会&#xff0c;今天我们就讲一讲这个鉴权到底是怎么回事。 一、什么是鉴权&#xff0c;为什么要鉴权 鉴权&#xff1a;是指是指验证用户是否拥有访问系统的权利。为什么要鉴权&#xff1a;…

常见的鉴权方式简述

一、什么是鉴权&#xff0c;为什么要鉴权 鉴权&#xff1a;是指验证用户是否有访问系统的权利。 为什么要鉴权 &#xff1a;对用户进行鉴权&#xff0c;防止非法用户占用网络资源&#xff0c;非法用户接入网络&#xff0c;被骗取关键信息 二、鉴权方式 Basic Auth basic au…

笔记——什么是鉴权

前言 鉴权是自动化测试路上的拦路虎&#xff1b;故以此记录鉴权到底是怎么回事。 一、什么是鉴权&#xff0c;为什么要鉴权 鉴权&#xff1a;是指验证用户是否有访问系统的权利。为什么要鉴权 &#xff1a;对用户进行鉴权&#xff0c;防止非法用户占用网络资源&#xff0c;非…

ftok()函数解析

ftok 消息队列、信号灯、共享内存常用在Linux服务端编程的进程间通信环境中。而此三类编程函数在实际项目中都是用System V IPC函数实现的。System V IPC函数名称和说明如下表15-1所示。 表15-1 System V IPC函数 消息队列 信号灯 共享内存区 头文件 <sys/msg.h> …

ftok()函数的使用

在上一篇文章中&#xff0c;Mayuyu讲述了共享内存的原理以及使用方法。在创建共享内存之前&#xff0c;必须指定一个ID值&#xff0c;而这个ID值通常是通过现在要讲的ftok()函数得到。ftok()函数原型如下 其中参数fname是指定的文件名&#xff0c;这个文件必须是存在的而且可以…

linux ftok函数的使用

ftok API #include <sys/types.h> #include <sys/ipc.h> key_t ftok(const char *pathname, int proj_id); ftok根据路径名&#xff0c;提取文件信息&#xff0c;再根据这些文件信息及project ID合成key&#xff0c;该路径可以随便设置。该路径是必须存在的&#x…

ftok与fork

ftok函数编辑 系统建立IPC通讯 &#xff08; 消息队列、 信号量和 共享内存&#xff09; 时必须指定一个ID值。通常情况下&#xff0c;该id值通过ftok函数得到。 2ftok原型编辑 头文件 #include < sys/types.h> #include <sys/ipc.h> 函数原型&#xff1a; key_t f…

Linux下的ftok()函数

linux ftok&#xff08;&#xff09;函数 - 清清飞扬 - 博客园 (cnblogs.com) 系统建立IPC通讯&#xff08;如消息队列、共享内存时&#xff09;必须指定一个ID值。通常情况下&#xff0c;该id值通过ftok函数得到。 ftok原型如下&#xff1a; key_t ftok( char * fname, int i…

Linux中ftok函数介绍

函数原型&#xff1a; *key_t ftok(const char fname, int id); 功能&#xff1a;系统建立IPC通讯&#xff08;如消息队列&#xff0c;共享内存时&#xff09;必须指定一个ID值。通常情况下&#xff0c;该id值通过ftok函数得到 返回值&#xff1a;成功返回一个key_t值&#xf…

linux ftok()

系统建立IPC通讯&#xff08;如消息队列、共享内存时&#xff09;必须指定一个ID值。通常情况下&#xff0c;该id值通过ftok函数得到。 ftok原型如下&#xff1a; C代码 key_t ftok( char * fname, int id) key_t ftok( char * fname, int id) fname就时你指定的文件名&a…

Linux中ftok函数详解

在ipc通信中 system V 模式的ipc通信中都需要一个key值来生成对应的ID&#xff0c;那么key是如何生成的呢&#xff1f; 通过函数ftok生成 #include <sys/types.h>#include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);参数&#xff1a; pathname: …

ftok说明

文章一&#xff1a; ftok函数 系统建立IPC通讯&#xff08;消息队列、信号量和共享内存&#xff09;时必须指定一个ID值。通常情况下&#xff0c;该id值通过ftok函数得到。 ftok原型 头文件&#xff1a; #include <sys/types.h> #include <sys/ipc.h> 如下&…

ftok()函数深度解析

关于ftok函数&#xff0c;先不去了解它的作用来先说说为什么要用它&#xff0c;共享内存&#xff0c;消息队列&#xff0c;信号量它们三个都是找一个中间介质&#xff0c;来进行通信的&#xff0c;这种介质多的是。就是怎么区分出来&#xff0c;就像唯一一个身份证来区分人一样…

linux进程间通信--消息队列相关函数(ftok)详解

ftok 消息队列、信号灯、共享内存常用在Linux服务端编程的进程间通信环境中。而此三类编程函数在实际项目中都是用System V IPC函数实现的。System V IPC函数名称和说明如下表15-1所示。 表15-1 System V IPC函数 消息队列 信号灯 共享内存区 头文件 <sys/msg.h> &l…

19-逆波兰表达式求值(栈)

逆波兰表达式求值 1.题目描述2. 思路3.代码实现3.1 c实现 4. 复杂度分析 1.题目描述 LeetCode题目链接 逆波兰表达式由波兰的逻辑学家卢卡西维兹提出。逆波兰表达式的特点是&#xff1a;没有括号&#xff0c;运算符总是放在和它相关的操作数之后。因此&#xff0c;逆波兰表达式…

逆波兰表达式求值

二元运算符的表达式定义为&#xff1a;(操作数) (运算符) (操作数) &#xff0c;其中操作数也可以为表达式。 在计算机中&#xff0c;根据运算符所在的不同位置来命名&#xff0c;表达式可以有如下三种不同的表示方法&#xff1a; 记表达式为&#xff1a;Exp S1 OP S2&a…