用户认证(Authentication)进化之路:由Basic Auth到Oauth2再到jwt

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 用户认证是一个在web开发中亘古不变的话题,因为无论是什么系统,什么架构,什么平台,安全性是一个永远也绕不开的问题在HTTP中,基本认证(Basic access authentication)是一种用来允许网页浏览器或其他客户端程序在请求时提供用户名和口令形式的身份凭证的一种登录验证方式。

用户认证是一个在web开发中亘古不变的话题,因为无论是什么系统,什么架构,什么平台,安全性是一个永远也绕不开的问题

在HTTP中,基本认证(Basic access authentication)是一种用来允许网页浏览器或其他客户端程序在请求时提供用户名和口令形式的身份凭证的一种登录验证方式。
虽然基本认证非常容易实现,但该方案创建在以下的假设的基础上,即:客户端和服务器主机之间的连接是安全可信的。特别是,如果没有使用SSL/TLS(https)这样的传输层安全的协议,那么以明文传输的密钥和口令很容易被拦截。该方案也同样没有对服务器返回的信息提供保护。
  现存的浏览器保存认证信息直到标签页或浏览器被关闭,或者用户清除历史记录。HTTP没有为服务器提供一种方法指示客户端丢弃这些被缓存的密钥。这意味着服务器端在用户不关闭浏览器的情况下,并没有一种有效的方法来让用户注销。

OAuth 是一个关于授权(authorization)的开放网络标准。允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。现在的版本是2.0版。
严格意义上来讲,OAuth2不是一个标准协议,而是一个安全的授权框架。它详细描述了系统中不同角色、用户、服务前端应用(比如API),以及客户端(比如网站或移动App)之间怎么实现相互认证。
最后,重点介绍一下JWT,JWT是一种安全标准。基本思路就是用户提供用户名和密码给认证服务器,服务器验证用户提交信息信息的合法性;如果验证成功,会产生并返回一个Token(令牌),用户可以使用这个token访问服务器上受保护的资源。

JWT 特点:
1 体积小,因而传输速度快
2 传输方式多样,可以通过URL/POST参数/HTTP头部等方式传输
3 严格的结构化。它自身(在 payload 中)就包含了所有与用户相关的验证消息,如用户可访问路由、访问有效期等信息,服务器无需再去连接数据库验证信息的有效性,并且 payload 支持为你的应用而定制化。
4 支持跨域验证,可以应用于单点登录。

JWT是Auth0提出的通过对JSON进行加密签名来实现授权验证的方案,编码之后的JWT看起来是这样的一串字符:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 

由 . 分为三段,通过解码可以得到:

1 Header头部分头部分简单声明了类型(JWT)以及产生签名所使用的算法。{"alg":"AES256","typ":"JWT"}

2 playload(载荷)中的Claims声明部分是整个token的核心,表示要发送的用户详细信息。有些情况下,我们很可能要在一个服务器上实现认证,然后访问另一台服务器上的资源;或者,通过单独的接口来生成token,token被保存在应用程序客户端(比如浏览器)使用。一个简单的声明(claim)的例子:{"sub":"1234567890","name":"John Doe","admin":true}

3 Signature签名签名的目的是为了保证上边两部分信息不被篡改。如果尝试使用Bas64对解码后的token进行修改,签名信息就会失效。一般使用一个私钥(private key)通过特定算法对Header和Claims进行混淆产生签名信息,所以只有原始的token才能于签名信息匹配。这里有一个重要的实现细节。只有获取了私钥的应用程序(比如服务器端应用)才能完全认证token包含声明信息的合法性。所以,永远不要把私钥信息放在客户端(比如浏览器)。

签名的目的:签名实际上是对头部以及载荷内容进行签名。所以,如果有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,那么新的头部和载荷的签名和之前的签名就将是不一样的。而且,如果不知道服务器加密的时候用的密钥的话,得出来的签名也一定会是不一样的。
这样就能保证token不会被篡改。

最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。类似盐

这里在第三步我们得到 JWT 之后,需要将JWT存放在 client,之后的每次需要认证的请求都要把JWT发送过来。(请求时可以放到 header 的 Authorization )

在web框架Django中的具体应用:

安装pyjwt

pip3 install pyjwt

在用户登录成功后,生成一个token

import jwt
encoded_jwt = jwt.encode({'username':'admin','site':'https://v3u.cn'},'secret_key',algorithm='HS256') 

将这个token交给前端,以后前端访问任意接口都将在header里带着这个令牌(token),用来做认证,然后我们肯定不能每一个视图方法都做验证,所以可以利用装饰器做一个统一用户认证模块

#定义验证装饰器
from django.http import JsonResponse
import jwt
def auth_required():
    def decorator(view_func):
        def _wrapped_view(self,request, *args, **kwargs):


            try:
                auth = request.META.get('HTTP_AUTHORIZATION').split()
            except AttributeError:
                return HttpResponse('没权限')
            
            try:
                dict = jwt.decode(auth[1], settings.SECRET_KEY, algorithms=['HS256'])
                username = dict.get('data').get('username')
            except jwt.ExpiredSignatureError:
                return JsonResponse({"status_code": 401, "message": "Token expired"})
            except jwt.InvalidTokenError:
                return JsonResponse({"status_code": 401, "message": "Invalid token"})
            except Exception as e:
                return JsonResponse({"status_code": 401, "message": "Can not get user object"})
            return view_func(request, *args, **kwargs)

        return _wrapped_view

    return decorator

至此,一个简单的jwt用户认证方法就写好了,至于jwt中的令牌存在客户端的什么位置呢?可以参考这一篇文章来寻找答案:彻底弄清楚session,cookie,sessionStorage,localStorage的区别及应用场景(面试向)

相关文章
|
4月前
|
JSON 安全 Java
使用Spring Boot和JWT实现用户认证
使用Spring Boot和JWT实现用户认证
|
2月前
|
安全 Java 数据安全/隐私保护
|
4月前
|
存储 JSON 安全
OAuth2与JWT在API安全中的角色:技术深度解析
【7月更文挑战第20天】OAuth2和JWT作为两种重要的安全协议,在API安全中发挥着不可或缺的作用。OAuth2通过提供灵活的授权框架,实现了对资源的细粒度访问控制;而JWT则通过其紧凑性和自包含性,确保了身份验证和信息传输的安全性。在实际应用中,将OAuth2和JWT结合使用,可以构建出既强大又安全的API服务,为用户提供更加安全、可靠和便捷的数字体验。
|
3月前
|
JSON 前端开发 Java
Spring Boot JWT 用户认证
Spring Boot JWT 用户认证
18 0
|
6月前
|
存储 JSON 前端开发
前端的JWT怎么进行用户认证?
前端的JWT怎么进行用户认证?
61 2
|
6月前
|
JSON 安全 网络安全
超详细的用户认证、权限、安全原理详解(认证、权限、JWT、RFC 7235、HTTPS、HSTS、PC端、服务端、移动端、第三方认证等等)
超详细的用户认证、权限、安全原理详解(认证、权限、JWT、RFC 7235、HTTPS、HSTS、PC端、服务端、移动端、第三方认证等等)
1057 0
|
6月前
|
安全 Java API
深度解析 Spring Security:身份验证、授权、OAuth2 和 JWT 身份验证的完整指南
Spring Security 是一个用于保护基于 Java 的应用程序的框架。它是一个功能强大且高度可定制的身份验证和访问控制框架,可以轻松地集成到各种应用程序中,包括 Web 应用程序和 RESTful Web 服务。 Spring Security 提供了全面的安全解决方案,用于身份验证和授权,并且可以用于在 Web 和方法级别上保护应用程序。
860 0
|
存储 JSON 安全
JWT验证用户信息功能与OAuth2协议
JWT验证用户信息功能与OAuth2协议
112 0
|
安全 Java 数据库
Spring Security并结合JWT实现用户认证(Authentication) 和用户授权(Authorization)
在Web应用开发中,安全一直是非常重要的一个方面。Spring Security基于Spring 框架,提供了一套Web应用安全性的完整解决方案。
658 0
|
存储 安全 算法
十七.SpringCloud+Security+Oauth2实现微服务授权 -非对称加密生成JWT令牌
SpringCloud+Security+Oauth2实现微服务授权 -非对称加密生成JWT令牌