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

本文涉及的产品
可观测可视化 Grafana 版,10个用户账号 1个月
函数计算FC,每月15万CU 3个月
应用实时监控服务-应用监控,每月50GB免费额度
简介: 【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 身份验证机制。

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

目录
相关文章
|
2月前
|
前端开发 JavaScript UED
探索Python Django中的WebSocket集成:为前后端分离应用添加实时通信功能
通过在Django项目中集成Channels和WebSocket,我们能够为前后端分离的应用添加实时通信功能,实现诸如在线聊天、实时数据更新等交互式场景。这不仅增强了应用的功能性,也提升了用户体验。随着实时Web应用的日益普及,掌握Django Channels和WebSocket的集成将为开发者开启新的可能性,推动Web应用的发展迈向更高层次的实时性和交互性。
101 1
|
1月前
|
JSON 安全 算法
Spring Boot 应用如何实现 JWT 认证?
Spring Boot 应用如何实现 JWT 认证?
71 8
|
1月前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
181 1
|
2月前
|
IDE 关系型数据库 MySQL
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
这篇文章是关于如何创建一个Django框架,介绍Django的项目结构和开发逻辑,并指导如何创建应用和编写“Hello, World!”程序的教程。
121 3
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
|
1月前
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
102 2
|
2月前
|
监控 应用服务中间件 网络安全
部署Django应用:使用Gunicorn和Nginx构建高效的生产环境
部署Django应用:使用Gunicorn和Nginx构建高效的生产环境
168 0
|
2月前
|
存储 开发框架 JSON
【查漏补缺】Django模型字段类型及其应用
【查漏补缺】Django模型字段类型及其应用
30 0
|
2月前
|
存储 安全 UED
GitHub OAuth认证的Django应用
GitHub OAuth认证的Django应用
30 0
|
3月前
|
JSON 安全 数据库
Python安全性大升级:OAuth与JWT,让你的应用穿上防弹衣🛡️
【9月更文挑战第6天】在数字世界中,每个应用都面临着安全威胁。作为Python开发者,构建强大的系统至关重要。OAuth和JWT为我们提供了坚实的安全保障。OAuth作为一种授权机制,让用户无需向第三方应用暴露敏感信息;JWT则通过自包含的信息传输,增强了安全性并提高了系统性能。利用Python生态中的这些工具,我们可以更好地保护用户数据,守护他们的信任与期待。下面是一个使用PyJWT生成和验证JWT的示例代码:(示例代码同上)通过这些技术,我们的应用能够更加稳健地在数字海洋中航行。
38 3