服务器验证——token

我们知道,http协议是无状态的,所以每次访问服务器的时候,都需要告诉服务器访问者的身份。在以前,我们常用Cookie+Session来完成服务器端验证。

具体过程为在客户端提交表单登录,服务器端通过验证之后,生成一个Session对象,存放用户登录信息,并将SessionID存放到Cookie中,通过Http响应发送到客户端。而客户端会在一定时间内保存cookie,此后的访问请求都会在请求头中带上Cookie的值,用于让服务器端验证,从而达到一次登录,后续不用验证的目的。

Session的缺点:

  • 当服务器访问量增加的时候,会存在很多Session,如果没有设置超时或者销毁的话,很容易造成服务器崩溃等状况。
  • 当服务端为集群或者分布式的时候,用户登陆其中一台服务器,会将session保存到该服务器的内存中,但是当用户的访问到其他服务器时,会无法访问,通常采用缓存一致性技术来保证可以共享,或者采用第三方缓存来保存session,不方便。

先来看看token的介绍:

Json Web Token:简称JWT,俗称token,它是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于网络应用环境间传递声明而执行的一种基于JSON的开放标准。JWT传递的信息可以被验证和信任,因为它是数字签名的。JWTs可以使用一个秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对来签名。

JWT 的三个部分依次如下:

Header(头部) Payload(负载) Signature(签名),写成一行,就是下面的样子。

Header.Payload.Signature

下面依次介绍这三个部分。

1. Header  头部

Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。

{ "alg": "HS256", "typ": "JWT" }

上面代码中,alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。

最后,将上面的 JSON 对象使用 Base64URL 算法转成字符串。

2. Payload  有效载荷

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。

iss (issuer):签发人

exp (expiration time):过期时间

sub (subject):主题

aud (audience):受众

nbf (Not Before):生效时间

iat (Issued At):签发时间

jti (JWT ID):编号

除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。

{ "sub": "1234567890", "name": "sssssss", "admin": true }

注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。

这个 JSON 对象也要使用 Base64URL 算法转成字符串。

3. Signature   签名

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

header (base64后的)

payload (base64后的)

secret(这个是服务器端自定义的一个秘钥)

这个部分需要base64加密后的header和base64加密后的payload使用连接组成的字符串,以及秘钥secret构成一个组合,然后通过header中声明的加密方式对这个组合进行加密,然后就构成了jwt的第三部分。

最后我们会得到完整的JWT:字符串1.字符串2.字符串3;

再来看看token是怎么做的:

1、客户端通过用户名和密码登录服务器

2、服务端对客户端身份进行验证;

3、服务端对该用户生成Token,返回给客户端;

4、客户端将Token保存到本地浏览器,一般保存到cookie中;

5、客户端发起请求,需要携带该Token;

6、服务端收到请求后,首先验证Token,之后返回数据。

服务端不需要保存Token,只需要对Token中携带的信息进行验证即可。无论客户端访问后台的那台服务器,只要可以通过用户信息的验证即可。

本人碰到的常用做法是用户登录验证通过后,将用户的uuid保存在JWT的有效载荷中并返回,之后的请求只要通过解析token获得用户的uuid,就可以对用户进行之后的操作。

防干扰:生成token的过程中,ua的充作干扰码。没有相同的ua,就无法解析生成的token字符串。如果客户端是混合开发的模式,生成token和使用token的代理可能不同(比如一个是h5,一个是原生),ua就会不同,token就无法成功的使用。

防过期(刷新):Token管理者负责根据用户的数据生成token和摘要,摘要用来给APP端刷新token用

 

 

 

### 关于Django中的CSRF Token验证导致403 Forbidden错误的原因 当在Django框架下执行POST请求时,如果未正确处理CSRF(跨站请求伪造)保护机制,则可能会触发`403 Forbidden`错误。此错误表明服务器拒绝了客户端的请求,因为所提供的CSRF令牌不匹配或缺失[^1]。 #### 解决方案一:确保模板中包含 `{% csrf_token %}` 标签 对于基于HTML表单的传统提交方式,在任何涉及POST方法的表单中都应嵌入Django提供的`{% csrf_token %}`标签。该标签会在页面渲染过程中自动生成隐藏字段并填充有效的CSRF令牌值[^2]。 ```html <form method="post"> {% csrf_token %} <!-- 其他表单项 --> </form> ``` #### 解决方案二:Ajax 请求中传递 CSRF Token 如果是通过JavaScript发起异步AJAX调用而非标准表单提交,则需手动设置HTTP头部携带CSRF令牌。以下是具体实现步骤: 1. **获取CSRF Token**: 可以从DOM元素或者Cookie中读取当前用户的CSRF令牌。 ```javascript function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken'); // 获取CSRF Token ``` 2. **配置 AJAX 请求头**: 使用jQuery库为例,可以通过如下代码全局设定每次AJAX请求自动附加CSRF令牌到指定头部位置。 ```javascript $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); ``` 上述操作能够有效防止由于缺少必要的安全凭证而导致的服务端拒绝响应问题[^3]。 #### 解决方案三:禁用特定视图上的CSRF防护 虽然通常建议保留CSRF防御措施来保障应用安全性,但在某些特殊场景下确实有必要绕过这一层校验逻辑。此时可以利用装饰器 `@csrf_exempt` 来豁免个别函数级别的检查需求。 注意这种方式仅适用于那些完全不需要考虑恶意攻击风险的功能模块上,并且应当谨慎评估潜在后果后再做决定。 ```python from django.views.decorators.csrf import csrf_exempt @csrf_exempt def my_view(request): ... ``` --- ### 总结 综上所述,针对Django项目里发生的因CSRF token不符而引发的403错误现象,主要可以从三个方面着手修正——确认前端已正确定义含CSRF标记的表单结构;调整JS脚本以便恰当传输对应参数至后端接口处接受检验;以及最后作为备选手段临时关闭部分区域内的防伪功能开关。以上任一种途径均能帮助开发者妥善应对此类状况的发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值