6

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

 2 years ago
source link: https://v3u.cn/a_id_98
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

首页 - Python/2019-07-16
用户认证(Authentication)进化之路:由Basic Auth到Oauth2再到jwt

    用户认证是一个在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的区别及应用场景(面试向)


Recommend

  • 16

    世界上最快的捷径,就是脚踏实地,本文已收录【 架构技术专栏 】关注这个喜欢分享的地方。 前序 最近想搞下基于Spring Cloud的认证授权平台,总体想法是可以对服务间授...

  • 16

    Spring Security OAuth2.0系列文章: Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Securi...

  • 8

    Spring Security OAuth2.0认证授权系列文章 Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring...

  • 17
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    OAuth2.0 认证

    目录 Oauth Oauth2.0 客户端应用注册 授权码模式(authorization code)流程 简化模式(Implicit Flow)流程 密码模式(Resource owner password credentials)流程 客户端模式(Cli...

  • 9

    Laravel+Passport+Vue实现Oauth2登录认证前情提要: 这里主要详诉一些细节和理论和部分代码,这里不讲Oauth2 是什么阮一峰: OAuth 2.0 的四种方式

  • 24

    How to use OAuth2 Proxy for central authentication 06/08/21 by

  • 12
    • driverzhang.github.io 3 years ago
    • Cache

    Golang实现oauth2认证

    Goalng实现oauth2.0认证授权 oauth2.0介绍: 这里不再多说给出参考链接 : 理解OAuth 2.0 总的来说,OAuth 不是一个API或者服务,而是一个验证授权...

  • 9

    OAuth2客户端按照它们与授权服务器进行安全认证的能力可以分为机密类型(Confidential)和公共类型(Public)。机密类型的自身会有个密码凭据,比如Web服务器后端程序;而公共类型则没有密码凭据,纯浏览器前端应用或者移动客户端应用大都属于这一种类型。不...

  • 14

    有很多页面都是没有登录验证的,比如prometheus,skywalking等,这个时候就可以使用oauth2-proxy去添加验证,oauth2-proxy本质是一个反向代理服务器...

  • 11

    客户体验管理,指的是战略性地管理客户对产品或公司全面体验的过程。随着互联网的发展,收集客户声音的渠道和方式出现革新,许多企业也开始探索、建立自己的客户体验管理系统。客户体验管理从幕后走向台前,都经历了什么?本文将为你解答。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK