zoukankan      html  css  js  c++  java
  • OAuth2认证和jwt机制

    一、OAuth2认证

    OAuth2是一个关于授权的开放标准,核心思路是通过各类认证手段(具体什么手段OAuth2不关心)认证用户身份,并颁发token(令牌),
    使得第三方应用可以使用该token(令牌)在限定时间、限定范围访问指定资源。

    OAuth2相关概念:

    资源所有者(resources owner):拥有被访问资源的用户
    客户端/第三方应用(client):第三方应用,获取资源服务器提供的资源
    授权服务器(authorization server):认证服务器,提供授权许可code、令牌token等
    资源服务器(resource server):资源服务器,拥有被访问资源的服务器,需要通过token来确定是否有权限访问

    OAuth2几种模式:
    获取令牌的方式主要有四种,分别是授权码模式、隐式授权码模式(简单模式)、密码模式和客户端模式。

    1)授权码模式(authorization code)
    这种模式是最安全的OAuth2的授权模式。设计了auth code,通过这个code再获取token,最后通过token获取资源。支持refresh token。

    应用场景:
    各大应用内的qq,微信,微博登录等。比如某应用内的qq登录,过程如下:
    a.用户点击qq登录,会先跳转到qq登录页面,这时请求已经跳转到qq服务器了,然后用户输入账号或者扫码登录,这时所有请求都在qq服务器完成。
    b.用户正确登录后,qq服务器返回用户的code给第三方应用,然后第三方应用再使用code去授权服务器请求获取token。(这一步用户不可见)
    c.第三方应用获取到token后,再使用token获取用户的qq名称,头像等信息。

    优缺点:
    优点:用户可以控制自身的一些权限是否给第三方,第三方只能获取到用户临时产生的一个访问的code,安全性。
    缺点:认证过程繁琐。

    2)隐式授权码模式/简单模式(implicit)
    和授权码模式类似,只不过少了获取code的步骤,是直接获取令牌token的,适用于公开的浏览器单页应用,令牌直接从授权服务器返回,不支持刷新令牌,且没有code安全保证,令牌容易因为被拦截窃听而泄露。
    不支持refresh token

    3)密码模式(resource owner password credentials)
    这种模式是最不推荐的,因为client可能存了用户密码
    这种模式主要用来做遗留项目升级为oauth2的适配方案
    当然如果client是自家的应用,也是可以
    支持refresh token

    4)客户端模式(client credentials)
    这种模式直接根据client的id和密钥即可获取token,无需用户参与
    这种模式比较合适消费api的后端服务,比如拉取一组用户信息等
    不支持refresh token,主要是没有必要

    二、JWT机制

    JWT概念:

    JWT全称为Json Web Token,随着微服务架构的流行而越来越火,号称新一代的认证技术。
    OAuth2中使用token验证用户登录合法性,但token最大的问题是不携带用户信息,资源服务器无法在本地进行验证,每次对于资源的访问,资源服务器都需要向认证服务器发起请求,一是验证token的有效性,二是获取token对应的用户信息。如果有大量的此类请求,无疑处理效率是很低,且认证服务器会变成一个中心节点,这在分布式架构下很影响性能。
    JWT就是在这样的背景下诞生的,从本质上来说,jwt和OAuth2没有可比性。普通的oauth2颁发的就是一串随机hash字符串,本身无意义,而jwt使用一种特殊格式的token,token是有特定含义的,分为三部分:
    -头部Header
    -载荷Payload
    -签名Signature
    这三部分均用base64进行编码,并使用.进行分隔。一个典型的jwt格式的token类似xxxxx.yyyyy.zzzzz。

    jwt其实并不是什么高深莫测的技术,相反非常简单。认证服务器通过对称或非对称的加密方式利用payload生成signature,并在header中申明签名方式,仅此而已。通过这种本质上极其传统的方式,jwt可以实现分布式的token验证功能,即资源服务器通过事先维护好的对称或者非对称密钥(非对称的话就是认证服务器提供的公钥),直接在本地验证token,这种去中心化的验证机制非常适合分布式架构。jwt相对于传统的token来说,解决以下两个痛点:
    1、通过验证签名,对于token的验证可以直接在资源服务器本地完成,不需要连接认证服务器;
    2、在payload中可以包含用户相关信息,这样就轻松实现了token和用户信息的绑定;
    如果认证服务器颁发的是jwt格式的token,那么资源服务器就可以直接自己验证token的有效性并绑定用户,这无疑大大提升了处理效率且减少了单点隐患。

    适用场景:
    一次性的身份认证、api的鉴权等,这些场景能充分发挥jwt无状态以及分布式验证的优势。

    不适用的场景:
    不要试图用jwt去代替session。这种模式下其实传统的session+cookie机制工作的更好,jwt因为其无状态和分布式,事实上只要在有效期内,是无法作废的,用户的签退更多是一个客户端的签退,服务端token仍然有效,你只要使用这个token,仍然可以登陆系统。另外一个问题是续签问题,使用token,无疑令续签变得十分麻烦,当然你也可以通过redis去记录token状态,并在用户访问后更新这个状态,但这就是硬生生把jwt的无状态搞成有状态了,而这些在传统的session+cookie机制中都是不需要去考虑的。

  • 相关阅读:
    线程
    网络编程
    正则表达式
    XML
    java----八种排序算法
    Java 关键字 速查表
    Day_19多线程(下)
    Day18_进程(中)
    Day17_进程(上)
    Day15_IO流(上)
  • 原文地址:https://www.cnblogs.com/alan6/p/12335416.html
Copyright © 2011-2022 走看看