HTTP Basic Authjavascript
HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RESTful API 使用的最简单的认证方式,只需提供用户名密码便可,但因为有把用户名密码暴露给第三方客户端的风险,在生产环境下被使用的愈来愈少。所以,在开发对外开放的RESTful API时,尽可能避免采用HTTP Basic Authjava
OAuthweb
OAuth(开放受权)是一个开放的受权标准,容许用户让第三方应用访问该用户在某一web服务上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。数据库
OAuth容许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每个令牌受权一个特定的第三方系统(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户能够受权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非全部内容后端
下面是OAuth2.0的流程:api
客户端:第三方应用,如微信...跨域
资源拥有者:用户浏览器
验证服务器:认证客户端的身份,最终颁发受权令牌(access token),在物理上,验证服务器能够和资源服务器由一个服务器来提供。安全
资源服务器:存储用户的资源,处理对资源的访问请求服务器
这种基于OAuth的认证机制适用于我的消费者类的互联网产品,如社交类APP等应用,可是不太适合拥有自有认证权限管理的企业应用;
如微信公众号的受权:
1. 用户关注微信公众帐号。
2. 微信公众帐号提供用户请求受权页面URL。
3. 用户点击受权页面URL,将向服务器发起请求
4. 服务器询问用户是否赞成受权给微信公众帐号(第一步,请求受权)
5. 用户赞成(scope为snsapi_base时无此步骤)
6. 服务器将CODE经过回调传给微信公众帐号(第二步,客户端获得用户的受权许可)
7. 微信公众帐号得到CODE
8. 微信公众帐号经过CODE向服务器请求Access Token(第三步)
9. 服务器返回Access Token和OpenID给微信公众帐号(第四步,服务器返回令牌)
10. 微信公众帐号经过Access Token向服务器请求用户信息(第五步)
11. 服务器将用户信息回送给微信公众帐号(scope为snsapi_base时无此步骤)
Cookie+session
HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里咱们把用户当作是客户端,客户端使用用户名还有密码经过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下。
Session,咱们须要在服务端存储为登陆的用户生成的 Session ,这些 Session 可能会存储在内存,磁盘,或者数据库里。咱们可能须要在服务端按期的去清理过时的 Session 。
当用户请求登陆的时候,若是没有问题,咱们在服务端生成一条记录,这个记录里能够说明一下登陆的用户是谁,而后把这条记录的 ID 号发送给客户端,客户端收到之后把这个 ID 号存储在 Cookie 里,下次这个用户再向服务端发送请求的时候,能够带着这个 Cookie ,这样服务端会验证一个这个 Cookie 里的信息,看看能不能在服务端这里找到对应的记录,若是能够,说明用户已经经过了身份验证,就把用户请求的数据返回给客户端。
基于 Token 的身份验证方法
使用基于 Token 的身份验证方法,在服务端不须要存储用户的登陆记录。大概的流程是这样的:
客户端使用用户名跟密码请求登陆
服务端收到请求,去验证用户名与密码
验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
客户端收到 Token 之后能够把它存储起来,好比放在 Cookie 里或者 Local Storage 里
客户端每次向服务端请求资源的时候须要带着服务端签发的 Token
服务端收到请求,而后去验证客户端请求里面带着的 Token,若是验证成功,就向客户端返回请求的数据
Token机制相对于Cookie机制又有什么好处呢?
支持跨域访问: Cookie是不容许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息经过HTTP头传输.
无状态(也称:服务端可扩展行):Token机制在服务端不须要存储session信息,由于Token 自身包含了全部登陆用户的信息,只须要在客户端的cookie或本地介质存储状态信息.
更适用CDN: 能够经过内容分发网络请求你服务端的全部资料(如:javascript,HTML,图片等),而你的服务端只要提供API便可.
去耦: 不须要绑定到一个特定的身份验证方案。Token能够在任何地方生成,只要在你的API被调用的时候,你能够进行Token生成调用便可.
更适用于移动应用: 当你的客户端是一个原平生台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你须要经过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
CSRF:由于再也不依赖于Cookie,因此你就不须要考虑对CSRF(跨站请求伪造)的防范。
性能: 一次网络往返时间(经过数据库查询session信息)总比作一次HMACSHA256计算 的Token验证和解析要费时得多.
不须要为登陆页面作特殊处理: 若是你使用Protractor 作功能测试的时候,再也不须要为登陆页面作特殊处理.
基于标准化:你的API能够采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft).
JWT
JSON Web Token(JWT)是一个很是轻巧的规范。这个规范容许咱们使用JWT在用户和服务器之间传递安全可靠的信息。一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
认证过程
登陆
第一次认证:第一次登陆,用户从浏览器输入用户名/密码,提交后到服务器的登陆处理的Action层(Login Action);
Login Action调用认证服务进行用户名密码认证,若是认证经过,Login Action层调用用户信息服务获取用户信息(包括完整的用户信息及对应权限信息);
返回用户信息后,Login Action从配置文件中获取Token签名生成的秘钥信息,进行Token的生成;
生成Token的过程当中能够调用第三方的JWT Lib生成签名后的JWT数据;
完成JWT数据签名后,将其设置到COOKIE对象中,并重定向到首页,完成登陆过程;
请求认证
基于Token的认证机制会在每一次请求中都带上完成签名的Token信息,这个Token信息可能在COOKIE中,也可能在HTTP的Authorization头中;
客户端(APP客户端或浏览器)经过GET或POST请求访问资源(页面或调用API);
认证服务做为一个Middleware HOOK 对请求进行拦截,首先在cookie中查找Token信息,若是没有找到,则在HTTP Authorization Head中查找;
若是找到Token信息,则根据配置文件中的签名加密秘钥,调用JWT Lib对Token信息进行解密和解码;
完成解码并验证签名经过后,对Token中的exp、nbf、aud等信息进行验证;
所有经过后,根据获取的用户的角色权限信息,进行对请求的资源的权限逻辑判断;
若是权限逻辑判断经过则经过Response对象返回;不然则返回HTTP 401;