深入理解令牌认证机制(token)
以前的开发模式是以MVC为主,但是随着互联网行业快速的发展逐渐的演变成了前后端分离,若项目中需要做登录的话,那么token成为前后端唯一的一个凭证。
token即标志、记号的意思,在IT领域也叫作令牌。在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。
token其实说的更通俗点可以叫暗号,在一些数据传输之前,要先进行暗号的核对,不同的暗号被授权不同的数据操作。例如在USB1.1协议中定义了4类数据包:token包、data包、handshake包和special包。主机和USB设备之间连续数据的交换可以分为三个阶段,第一个阶段由主机发送token包,不同的token包内容不一样(暗号不一样)可以告诉设备做不同的工作,第二个阶段发送data包,第三个阶段由设备返回一个handshake包。
在HTTP请求中使用承载令牌来访问OAuth 2.0受保护的资源。拥有承载令牌的任何一方(“承载方”)都可以使用它访问相关资源(无需证明拥有加密密钥)。为了防止误用,需要防止在存储和传输中泄露承载令牌。
OAuth允许客户端通过获取访问令牌,它在“OAuth 2.0授权”中定义框架“[RFC6749]作为”表示访问的字符串而不是使用资源直接服务的凭证。
该令牌由服务端允许的情况下,由客户端通过某种方式向服务端发出请求,由服务端向客户端发出,客户机使用访问令牌访问由资源服务器承载的受保护的资源。该规范描述了当OAuth访问令牌是承载令牌时,如何发出受保护的资源请求。
客户端只需要拥有token可以以任何一种方法传递token,客户端需要知道参数加密的密钥,只需要存储token即可。
OAuth为客户端提供了一种方法来代表资源所有者访问受保护的资源。在一般情况下,客户机在访问受保护的资源之前,必须首先从资源所有者获得授权,然后将授权交换为访问令牌。访问令牌表示授权授予授予的范围、持续时间和其他属性。客户机通过向资源服务器显示访问令牌来访问受保护的资源。在某些情况下,客户端可以直接向服务端显示的发送自己的凭证。
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
此方案的Authorization头字段的语法遵循[RFC2617]第2节中定义的基本方案的用法。注意,与Basic一样,它不符合[RFC2617]第1.2节中定义的通用语法,但与正在为HTTP 1.1 [HTTP- auth]开发的通用身份验证框架兼容,尽管它没有遵循其中列出的反映现有部署的首选实践。承载凭证的语法如下
b64toke = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"="
credentials = "Bearer" 1*SP b64token
客户端应该使用带有承载HTTP授权方案的Authorization请求头字段使用承载令牌发出经过身份验证的请求。资源服务器必须支持此方法。
在Internet Engineering Task Force (IETF)的白皮书中介绍Bearer Token的使用方法,那么我们平时使用token的时候姿势是否正确。应该如何正确使用token呢?
import axios from "axios";
axios.interceptors.request.use(config => {
if (store.state.token) {
config.headers.authorization = `Basic ${store.state.token}`;
}
return config;
});
照白皮书所说这样才是正确使用token的姿势。小伙伴们平时你们使用token的时候是这样的吗?
那么除了前端有明确的使用规范,那么服务端又应该怎样有效的做好后端数据防护?在白皮书中同样也有提到过。
根据OAuth 2.0动态客户端注册协议该规范定义了向授权服务器动态注册OAuth 2.0客户端的机制。注册请求向授权服务器发送一组所需的客户端元数据值(token)。结果的注册响应返回要在授权服务器上使用的客户机标识符和为客户机注册的客户机元数据值。然后,客户机可以使用此注册信息使用OAuth 2.0协议与授权服务器通信。该规范还定义了一组通用客户端元数据字段和值,供客户端在注册期间使用。
为了让OAuth 2.0 [RFC6749]客户机利用OAuth 2.0授权服务器,客户机需要与服务器交互的特定信息,包括在该服务器上使用的OAuth 2.0客户端标识符。该规范描述了如何通过授权服务器动态注册OAuth 2.0客户端来获取此信息。
抽象的动态客户端注册流程
+--------(A)- Initial Access Token (OPTIONAL)
|
| +----(B)- Software Statement (OPTIONAL)
| |
v v
+-----------+ +---------------+
| |--(C)- Client Registration Request -->| Client |
| Client or | | Registration |
| Developer |<-(D)- Client Information Response ---| Endpoint |
| | or Client Error Response +---------------+
+-----------+
图中所示的抽象OAuth 2.0客户机动态注册流描述了客户机或开发人员与此规范中定义的端点之间的交互。此图没有显示错误条件。这个流程包括以下步骤
- 可选地,向客户端或开发人员发出初始访问令牌,允许访问客户端注册端点。向客户端或开发人员发出初始访问令牌的方法超出了本规范的范围。
- 客户端或开发人员可以选择发布一个软件声明,以便与客户端注册端点一起使用。向客户端或开发人员发出软件声明的方法超出了本规范的范围。
- 客户端或开发人员使用客户端所需的注册元数据调用客户端注册端点,如果授权服务器需要初始访问令牌,则可以选择包含来自(A)的初始访问令牌。
- 授权服务器注册客户机并返回客户端注册的元数据, 在服务器上唯一的客户端标识符,以及一组客户端凭据,如客户端机密(如果适用于此客户端)。
授权类型与响应类型之间的关系
描述的“grant类型”和“响应类型”值是部分正交的,因为它们引用传递到OAuth协议中不同端点的参数。但是,它们是相关的,因为客户机可用的grant类型影响客户机可以使用的响应类型,反之亦然。例如,包含授权代码的授权类型值意味着包含代码的响应类型值,因为这两个值都定义为OAuth 2.0授权代码授权的一部分。因此,支持这些字段的服务器应该采取步骤,以确保客户机不能将自己注册到不一致的状态,例如,通过向不一致的注册请求返回无效的客户机元数据错误响应。
下表列出了这两个字段之间的相关性。
+-----------------------------------------------+-------------------+
| grant_types value includes: | response_types |
| | value includes: |
+-----------------------------------------------+-------------------+
| authorization_code | code |
| implicit | token |
| password | (none) |
| client_credentials | (none) |
| refresh_token | (none) |
| urn:ietf:params:oauth:grant-type:jwt-bearer | (none) |
| urn:ietf:params:oauth:grant-type:saml2-bearer | (none) |
+-----------------------------------------------+-------------------+
向授予类型或响应类型参数引入新值的此文档的扩展和概要文件必须记录这两种参数类型之间的所有通信。
如果发送任何人类可读的字段时没有使用语言标记,那么使用该字段的各方不能对字符串值的语言、字符集或脚本做出任何假设,而且字符串值必须按照在用户界面中显示的位置使用。为了促进互操作性,建议客户端和服务器除了使用任何特定于语言的字段外,还使用不使用任何语言标记的人可读字段,并且建议发送的任何不使用语言标记的人可读字段包含适合在各种系统上显示的值。
例如,软件声明可以包含以下声明:
{
"software_id": "4NRB1-0XZABZI9E6-5SM3R",
"client_name": "Example Statement-based Client",
"client_uri": "https://client.example.net/"
}
以下非标准示例JWT包括这些声明,并且使用RS256(仅用于显示目的)进行了非对称签名。并等到如下加密字符串。
eyJhbGciOiJSUzI1NiJ9.
eyJzb2Z0d2FyZV9pZCI6IjROUkIxLTBYWkFCWkk5RTYtNVNNM1IiLCJjbGll
bnRfbmFtZSI6IkV4YW1wbGUgU3RhdGVtZW50LWJhc2VkIENsaWVudCIsImNs
aWVudF91cmkiOiJodHRwczovL2NsaWVudC5leGFtcGxlLm5ldC8ifQ.
GHfL4QNIrQwL18BSRdE595T9jbzqa06R9BT8w409x9oIcKaZo_mt15riEXHa
zdISUvDIZhtiyNrSHQ8K4TvqWxH6uJgcmoodZdPwmWRIEYbQDLqPNxREtYn0
5X3AR7ia4FRjQ2ojZjk5fJqJdQ-JcfxyhK-P8BAWBd6I2LLA77IG32xtbhxY
fHX7VhuU5ProJO8uvu3Ayv4XRhLZJY4yKfmyjiiKiPNe-Ia4SMy_d_QSWxsk
U5XIQl5Sa2YRPMbDRXttm2TfnZM1xx70DoYi8g6czz-CPGRi4SW_S2RKHIJf
IjoI3zTJ0Y2oe0_EJAiXbL6OyF9S5tKxDXV8JIndSA
加密字符串由头,载荷以及密钥通过一系列的速算法生成,加密字符串与头,载荷以及密钥息息相关,一但加密字符串稍有改动,则无法解析正确解析无法通过验证。
通过加密字符串向授权服务器注册客户端。授权服务器为该客户端分配一个惟一的客户端标识符,可选地分配一个客户端机密,并将请求中提供的元数据与已发布的客户端标识符关联起来。该请求包括在注册期间为客户端指定的任何客户端元数据参数。授权服务器可以为客户端元数据中遗漏的任何项提供默认值。
注册端点,内容类型为application/json。该HTTP Entity Payload是一个由JSON组成的JSON文档对象和所有请求的客户端元数据值作为顶级成员那个JSON对象。
示例:
const Koa = require("koa");
const Router = require("koa-router");
const jwt = require("jsonwebtoken");
const jwtAuth = require("koa-jwt");
const secret = "it's a secret"; // 密钥
const app = new Koa();
const router = new Router();
router.get('/api/login',async (ctx) => {
const {username,passwd} = ctx.query;
if(username === "aaron" && passwd == "123456"){
const token = jwt.sign({
data:{name:"Aaron",userId:"1"}, // 用户信息
exp:Math.floor(Date.now()/1000)+60*60 // 过期时间
},secret);
ctx.body = {code:200,token};
}
else{
ctx.status = 401;
ctx.body = {code:0,message: "用户名密码错误"};
}
});
router.get("/api/userinfo",jwtAuth({secret}),async (ctx) => { // jwtAuth受保护路由
ctx.body = {code:200,data:{name:"Aaron",age:18}}
});
app.use(router.routes());
app.listen(3000);
因为最后生成的token是通过base64加密的,有些内容是可以反解的,所以千万不要在数据里面添加有关数据的敏感信息。注意注意。。。
深入理解令牌认证机制(token)的更多相关文章
- 开源干货!!!.NET Core + JWT令牌认证 + Vue.js(iview-admin) 通用动态权限(RBAC)管理系统框架[DncZeus]开源啦!!!
DncZeus 前言 关于 DncZeus DncZeus = Dnc + Zeus "Dnc"--.Net Core 的缩写: "Zeus"--中文译为宙斯, ...
- 基于Token的WEB后台认证机制
几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...
- 【转】基于Token的WEB后台认证机制
原谅地址:http://www.cnblogs.com/xiekeli/p/5607107.html 几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每 ...
- Jmeter的代理和cookie/session/Token令牌认证
Jmeter的代理服务器 1.启动Jmeter: 2.“测试计划”中添加“线程组”: 3.“工作台”中添加“HTTP代理服务器”: 4.配置代理服务器:Global Settings下面的端口配置:9 ...
- iOS 开发之基于JWT的Token认证机制及解析
在移动端和服务端通信中,一般有两种认证方式:token 和 session. 1.session/cookie 认证机制: 在服务端创建一个Session对象,同时在客户端的浏览器端创建一个Cooki ...
- 基于JWT的Token认证机制及安全问题
[干货分享]基于JWT的Token认证机制及安全问题 https://bbs.huaweicloud.com/blogs/06607ea7b53211e7b8317ca23e93a891
- 理解JWT(Json Web Token)
这篇文章写得不错: 理解JWT(JSON Web Token)认证及python实践,这里不做转载,仅摘要如下,有删改,仅做个人学习,感谢原作者. 常用认证机制: 1)HTTP basic Auth: ...
- RESTful API架构和oauth2.0认证机制(概念版)
1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...
- WEB后台认证机制
mark to :http://www.cnblogs.com/xiekeli/p/5607107.html HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API ...
随机推荐
- AUTOSAR-关于配置文件的思考
基于Can: 1. Can_Cfg.h contains compile time configurations. It should be included by Can.h which is sp ...
- FastDFS单机版安装
FastDFS 分布式文件系统 1 目标 了解项目中使用FastDFS的原因和意义. 掌握FastDFS的架构组成部分,能说出tracker和storage的作用. 了解FastDFS+nginx上传 ...
- python_code list_3
>>> seq=['foo','x41','?','***']>>> def func(x): return x.isalnum() >>> li ...
- SpringBoot开发案例从0到1构建分布式秒杀系统
前言 最近,被推送了不少秒杀架构的文章,忙里偷闲自己也总结了一下互联网平台秒杀架构设计,当然也借鉴了不少同学的思路.俗话说,脱离案例讲架构都是耍流氓,最终使用SpringBoot模拟实现了部分秒杀场 ...
- PAT1027:Colors In Mars
1027. Colors in Mars (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue People ...
- Python初级教程
Python语言的特点 优点: - 简单 - 易学 - 免费,开源 - 高层语言 - 可移植性(可再多平台运行) - 解释性(不需要编译,可直接运行) - 面向对象 - 可扩展性(缺点:运行效率相对较 ...
- Linux时间子系统之四:Timer在用户和内核空间流程
用户空间应用中创建一个Timer(alarm/setitimer/POSIX Timer等等),然后程序继续执行: 内核进入创建/设置Timer系统调用,开始计时,在超时后通过何种方式通知用户空间: ...
- PHP设计模式 -- 注册模式
参考文章:https://segmentfault.com/a/1190000007495855 简介 注册树模式又称注册模式或注册器模式.注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候 ...
- setInterval setTimeout 详解
JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如 setTimeout( ...
- Django+Bootstrap+Mysql 搭建个人博客(六)
6.1.comments插件 (1)安装 pip install django-contrib-comments (02)settings INSTALLED_APPS = [ 'django.con ...