在django3应用中使用现代的JWT鉴权

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
容器镜像服务 ACR,镜像仓库100个 不限时长
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: 【6月更文挑战第8天】本文介绍流行的鉴权方式,JSON Web Tokens (JWT) 是一种验证JSON数据所有者的机制,它是一个编码的、安全的字符串,包含可信任的数据且能加密签名。无状态的令牌认证允许客户端存储令牌并将其在每次请求。

1 简介:

什么是JSON的web令牌?

JWT 是一种验证某些 JSON 数据所有者的机制。它是一个编码的、URL 安全的字符串,可以包含无限量的数据(与 cookie 不同),并且可以经过加密签名。

question_ans.png

JWT包含标准字段如aud(受众)、exp(过期时间)、iss(发行者)、sub(主题)和jti(唯一标识),用于客户端身份验证。JWT分为自签名类型,如OAuth 2.0中的client_secret_jwtprivate_key_jwt

当服务器收到 JWT 时,它可以保证它包含的数据是可信的,因为它是由源签名的。一旦发送加密JWT,任何中间人都无法对其进行修改。

2 JWT常用携带字段

为客户端身份验证(或)创建 JWT 断言声明时,收集 JWT 的有效负载部分的声明信息。声明是有关实体的语句,实体通常是用户和任何其他数据。

可以自定义字段名,也可以使用常用的字段名如下,

字段名                         类型描述
aud         尝试使用 JWT 进行身份验证的资源的完整 URL。
                  例如:https://${yourOktaDomain}/oauth2/default/v1/token    字符串

exp     自  1970 年1月1日的  UTC时间戳(UNIX 时间戳)以来的令牌过期时间(以秒为单位),
         例如整数 1557594819 
        如果过期时间在未来超过一小时或令牌已过期,则此声明会使请求失败。

iss     令牌的颁发者。此值必须与您正在访问的应用程序的值相同。
           例如 client_id    字符串  必填。

sub      令牌的主题。此值必须与您正在访问的应用程序的值相同。
            例如 client_id    字符串

jti      唯一令牌标识符。如果指定此参数,则令牌只能使用一次,
           因此后续令牌请求不会成功。    字符串

iat     例如,UTC(UNIX 时间戳)以来以秒为单位颁发令牌时,
            例如整数 1557594819 .如果指定,则必须是收到请求之前的时间。 

3 自签名令牌认证 Token Authentication

不同的框架常常有不同的算法实现,比如在OAuth 2.0中常用的可以生成两种类型的自签名 JWT ,以便在向需要客户端身份验证的终结点发出请求时使用:

具有共享密钥 (client_secret_jwt)
带有私钥的 JWT (private_key_jwt)

构建这两种类型的断言之间的区别在于用于对 JWT 进行签名的算法和密钥。

您使用的 JWT 类型取决于客户端应用程序中配置的客户端身份验证方法。

使用共享密钥构建 JWT,如果将应用程序配置为使用客户端身份验证方法,则需要生成使用 HMAC SHA 算法(HS256、HS384 或 HS512)进行签名的 JWT。

令牌认证的主要方法(以及我们将在BlogAPI中实现的一种方法)是使用令牌验证 JSON Web Token (JWT, 发音 jot) 。这是近年来最流行的方法应用程序。

基于令牌的身份验证是无状态的:客户端将初始用户凭据发送至服务器生成唯一的令牌,然后由客户端将其存储为cookie或本地储存。

然后,此令牌在每个传入HTTP请求的标头中传递,服务器使用它来验证用户已通过身份验证。服务器本身不保留用户记录,以及令牌是否有效。

Cookies vs localStorage

Cookies用于读取服务器端信息。它们较小(4KB),并随每个HTTP请求自动发送。 LocalStorage专为客户端信息而设计。它更大(5120KB),默认情况下,不会在每个HTTP请求都发送其内容。

Cookie和localStorage中存储的令牌很容易受到XSS攻击。

目前最佳做法是使用httpOnly和Securecookie标志将令牌存储在cookie中。

让我们看一下此 挑战/响应流 ( challenge/response)中的实际HTTP消息的简单版本。注意HTTP标头WWW-Authenticate指定在响应中使用的令牌的使用授权标头请求。

示意图表 Diagram

    Client                     Server
                     -------->
   GET / HTTP/1.1
                         <----------- HTTP/1.1 401 Unauthorized WWW-Authenticate: Token
                    ---------->
  GET / HTTP/1.1
 Authorization: 
 Token 401f7ac837da4dawdaw613d789819ff93537bee6a

                           <--------- 
                                            HTTP/1.1 200 OK

这种方法有很多好处。由于令牌存储在客户端上,因此扩展维护最新会话对象的大型服务器不再是问题。

令牌可以共享在多个前端之间:相同的令牌可以代表网站上的用户,并且相同用户在移动应用上。

Django_REST_Framework 令牌内建库 TokenAuthentication 是很基础的,不支持设置令牌到期,这是可以添加的安全性改进。

它也只会产生一个令牌,因此网站上的用户以及后来的移动应用程序都将使用相同的令牌。

由于有关用户的信息存储在本地,这需要更新两组客户信息 因此可能导致维护和维护方面的问题。

可以添加到Django的令牌的增强版本可以通过多个第三方程序包的REST框架。

JWT有很多好处,包括生成唯一客户端令牌和令牌到期的能力。它们可以在服务器生成或第三方服务(如Auth)。

而且JWT可以被加密,这使得它们可以更安全地通过不安全的HTTP连接发送,也补充了http的不安全性。

4 使用框架自带的功能实现令牌认证

对于大多数Web API而言,最安全的选择是使用基于令牌的身份验证方案。
JWTs是不错的,是现代的补充,尽管它们需要其他配置。

在这里我们将使用rest_framework内置的TokenAuthentication。

  • 第一步 配置我们的新身份验证设置。

    Default Authentication
    Django REST框架来了具有许多隐式设置的设置。

    例如,DEFAULT_PERMISSION_CLASSES在我们将其更新为IsAuthenticated之前,将其设置为AllowAny。 明确config/setting默认认证配置如下

         REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [
             'rest_framework.permissions.IsAuthenticated', ],
         'DEFAULT_AUTHENTICATION_CLASSES': [ # new
             'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication'],
             }
    

    要同时使用两种方法,答案是它们有不同的用途。会话用于提供可浏览的API以及登录和注销该API的能力。 BasicAuthentication 用于传递API本身的HTTP标头中的会话ID。

  • 第二步,设置DEFAULT_AUTHENTICATION_CLASSES TokenAuthentication

     # config/settings.py
     REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [
     'rest_framework.permissions.IsAuthenticated',
     ],
     'DEFAULT_AUTHENTICATION_CLASSES': [
     'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', # new
     ],}
    
  • 第三步,添加token认证到 全局 setting设置 INSTALLED_APPS

     'rest_framework.authtoken' 
    
  • 第四步, 我们对INSTALLED_APPS进行了更改,因此我们需要同步数据库

     python manager.py migrate
    

使用superuser 管理员,你会看到那里现在顶部的“令牌”部分。确保您使用超级用户帐户登录后才能有 token 使用权。

由于几乎所有的API需要此功能,因此有几个优秀且经过测试的第三方可以满足 token的创建和管理功能。

5 小结

请注意,JWT 保证数据所有权,但不保证加密。

任何截获令牌的人都可以看到存储到 JWT 中的 JSON数据,因为它只是序列化的,而不是加密的。

出于这个原因,强烈建议将HTTPS与JWT(顺便说一下,还有一般的HTTPS)一起使用。

JWT 是一种特别有用的 API 身份验证和服务器到服务器授权技术。
但是会话操作时, 不应将 JWT 用作会话令牌。

首先,JWT 具有广泛的功能和大范围适用场景,这增加了库作者或用户出错的可能性。

其次是,您无法在会话结束时删除 JWT,因为它是独立的,并且没有中央机构使它们无效。

最后, JWT相对较大。当与 cookie 一起使用时,每个请求都传输可能增加开销。
  • 主要局限性:

    相同的会话ID不能在不同的前端之间共享
    
  • 缺点:

    潜在的不利因素是令牌可能会变得很大。令牌包含所有用户信息,不仅是ID,还有会话ID /会话对象的设置。

    由于令牌是根据每个请求发送的,管理其大小可能会成为性能问题。
    令牌的实施方式也可能有很大不同。

总体而言,这是一种非常流行的标准,可用于通过使用签名来信任请求,并在各方之间交换信息。
JWT 的一个非常常见的用途——也许是最好的用途——是作为 API 身份验证机制。

确保您知道何时最好使用,何时最好使用其他方法,以及如何防止最基本的安全问题。

目录
相关文章
|
1月前
|
存储 缓存 数据库
【万字长文】微服务整合Shiro+Jwt,源码分析鉴权实战
介绍如何整合Spring Boot、Shiro和Jwt,以实现一个支持RBAC的无状态认证系统。通过生成JWT token,实现用户无状态登录,并能根据用户角色动态鉴权,而非使用Shiro提供的注解,将角色和权限信息硬编码。此外,文章还探讨了如何对Shiro的异常进行统一捕获和处理。作为应届生,笔者在学习Shiro的过程中进行了一些源码分析,尽管可能存在不足和Bug,但希望能为同样需要实现权限管理的开发者提供参考,并欢迎各位大佬指正完善。
187 65
【万字长文】微服务整合Shiro+Jwt,源码分析鉴权实战
|
1月前
|
API 数据安全/隐私保护 网络架构
在django3中配置应用的权限
【6月更文挑战第9天】该文档介绍了Django REST Framework的权限管理。总结来说,本文介绍如何设置严格项目权限和如何通过自定义权限控制对特定资源的访问。
33 10
在django3中配置应用的权限
|
1月前
|
存储 安全 API
在django中创建项目时应用基础鉴权
【6月更文挑战第7天】本文探讨了在django中的API权限管理,即用户认证的两种方法:基础认证和会话认证。Django REST Framework默认使用会话认证,但也提供基础、令牌和JWT等其他选项。根据项目需求,应谨慎选择适合的认证方案。
65 3
在django中创建项目时应用基础鉴权
|
14天前
|
存储 前端开发 JavaScript
探索Django:打造高效、可扩展的Web应用(中)
探索Django:打造高效、可扩展的Web应用(中)
15 1
|
1月前
|
安全 API 数据安全/隐私保护
在django应用中使用权限控制
【6月更文挑战第6天】本文介绍在Django REST Framework中,项目权限通过默认设置如AllowAny、IsAuthenticated等管理。通过定制权限策略,确保了API的安全访问。
76 1
在django应用中使用权限控制
|
16天前
|
中间件 开发者 C++
Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用
Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用
|
16天前
|
前端开发 Python
Django框架中Ajax GET与POST请求的实战应用
Django框架中Ajax GET与POST请求的实战应用
|
27天前
|
存储 流计算 Python
使用Django构建即时通讯应用的最简单方法
使用Django构建即时通讯应用的最简单方法
|
1月前
|
存储 安全 数据库
在django应用中使用会话提示用户体验
【6月更文挑战第12天】该文档介绍了Django中如何利用会话(session)为用户提供定制体验。通过会话,开发者能更好地管理和个性化匿名用户的网站体验。参考[Django官方文档](https://docs.djangoproject.com/en/4.0/top
22 2
|
1月前
|
API 数据库 网络架构
在django中应用视图和路由集
【6月更文挑战第10天】 本文介绍viewsets`和`Routers`是Django REST framework中用于简化API视图和路由的工具。它们提供了一个抽象层,允许用更少的代码替代多个相关视图,并能自动生成URL。定义`UserList`和`UserDetail`视图集,分别用于列表和详情展示。
16 3