认证

作者: 零下的雨 | 来源:发表于2018-12-28 15:13 被阅读0次

基本权限认证分为OAuth认证,摘要认证和基本认证,证书认证,表单认证

OAuth 认证流程详解:

摘抄自:https://www.jianshu.com/p/0db71eb445c8
很多网站、APP 弱化甚至没有搭建自己的账号体系,而是直接使用社会化登录的方式,这样不仅免去了用户注册账号的麻烦、还可以获取用户的好友关系来增强自身的社交功能。

比如我们可以使用微博登录简书,简书会自动将你的微博头像设置为你的简书头像,将你的微博昵称设置为你的简书昵称,甚至还可以获取你微博中的好友列表,提示你哪些朋友已经在使用简书,这是如何做到的呢?

最传统的办法是让用户直接在简书的登录页面输微博的账号和密码,简书通过用户的账号和密码去微博那里获取用户数据,但这样做有很多严重的缺点:

  1. 简书需要明文保存用户的微博账号和密码,这样很不安全。
  2. 简书拥有了获取用户在微博所有的权限,包括删除好友、给好友发私信、更改密码、注销账号等危险操作。
  3. 用户只有修改密码,才能收回赋予简书的权限。但是这样做会使得其他所有获得用户授权的第三方应用程序全部失效。
  4. 只要有一个第三方应用程序被破解,就会导致用户密码泄漏,以及所有使用微博登录的网站的数据泄漏。

为了解决以上的问题,OAuth 协议应运而生。

原理概要

新浪微博作为服务提供商,拥有用户的头像、昵称、邮箱、好友以及所有的微博内容,简书希望获取用户存储在微博的头像和昵称,假设它们是三个人:

  1. 简书问新浪微博:我想要获取用户 A 的头像和昵称,请你提供
  2. 微博说:我需要经过用户A 本人的许可,然后去问用户 A 是否要授权简书访问自己的头像和昵称
  3. 用户 A 对微博说:我给简书一个临时的钥匙,如果他给你出示了这把钥匙,你就把我的资料给他
  4. 简书使用户给它的钥匙获取用户头像和昵称信息。

以上是 OAuth 认证的大概流程。在使用微博授权之前,简书需要先在微博开放平台上注册应用,填写自己的名称、logo、用途等信息,微博开放平台颁发给简书一个应用 ID 和叫 APP Secret 的密钥,在实际对接中,会使用到这两个参数。

详细流程

image

接下来分步详细解释上图中每步都做了什么:

  1. 用户点击简书上的微博登录按钮,跳转到微博授权页面。微博登录按钮的链接形如下方的 URL:

      https://api.weibo.com/oauth2/authorize?client_id=123050457758183&redirect_uri=http://jianshu.com/callback
    
    

URL 中要包含以下参数:

  • client_id:在微博开放平台申请的应用 ID
  • redirect_uri:授权成功后要跳转到的地址

点击以上链接后跳转到微博的授权页面如下图:

image

这个页面会告诉用户第三方应用要获取用户的哪些数据,以及拥有什么权限,比如在上图中简书会要求获得个人信息、好友关系、分享内容到微博以及获得评论的权限,用户点击“允许”则表示允许简书获得这些数据,进行下一步

  1. 页面自动跳转到初始参数中redirect_uri 定义的那个URL,并自动在 URL 末尾添加一个 code 参数,实际跳转的地址形如:

     http://jianshu.com/callback?code=2559200ecd7ea433f067a2cf67d6ce6c
    
    
  2. 第三步,简书通过上一步获取的 code 参数换取 Token,Token 就是前文中说到的钥匙。简书请求如下的接口获取 Token:
    POST https://api.weibo.com/oauth2/access_token
    要包含以下参数:

    • client_id:在微博开放平台申请的应用 ID
    • client_secret:在微博开放平台申请时提供的APP Secret
    • grant_type:需要填写authorization_code
    • code:上一步获得的 code
    • redirect_uri:回调地址,需要与注册应用里的回调地址以及第一步的 redirect_uri 参数一致
  3. 通过第三步的请求,接口返回 Token 和相关数据:

    {
     "access_token": "ACCESS_TOKEN",//Token 的值
     "expires_in": 1234,//过期时间
     "uid":"12341234"//当前授权用户的UID。
    }
    
    
  4. 在第四步中获取了access_token ,使用它,就可以去获取用户的资源了,要获取用户昵称和头像,请求如下接口:
    GET https://api.weibo.com/2/users/show.json

    携带参数:

    • access_token:上一步获取的access_token
    • uid:用户的账号 id,上一步的接口有返回
  5. 最后一步,微博返回用户信息,简书进行处理,整个流程结束。

通过以上的方式,在简书和新浪微博中间建立了一个独立的权限层,这个权限由用户赋予,可以被用户随时取消,不同第三方应用之间相互独立,互不干扰,这样就彻底解决了明文存放账号密码的问题。

以上只是以新浪微博为例,概括了一种最常见的 OAuth2.0 认证方式,关于 OAuth 更全面的文档,请参见 RFC 6749。阮一峰博客上也写过一篇关于 OAuth 的科普,推荐阅读:《理解OAuth 2.0

作者:耗子吴
链接:https://www.jianshu.com/p/0db71eb445c8
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

基本认证与摘要认证

摘抄自:https://www.cnblogs.com/yanze/p/9177002.html
浏览器与服务端之间可以通过cookie进行身份验证,那么,桌面应用程序与服务端呢?

BASIC认证(基本认证)

当客户端向服务端进行数据请求时,如果客户端尚未被认证,则http服务器将使用基本认证对客户端的用户名密码进行认证,以确认用户是否合法,一般方法为 将 用户名:密码 用base64加密后放入请求头中的Authorization,再发送给服务器,此方式为基本认证。

基本认证也能用于浏览器端,但相对较少。

基本认证过程:

1.http请求头中添加Authorization: Basic + base64加密字段

2.验证通过,返回内容;验证不通过,返回头中的WWW-Authenticate中会有相关说明

备注: 基本认证使用base64编码,安全性低容易解码,因此一般使用HTTPS传输,相对安全性会高一些。

Digest认证(摘要认证)

http1.1中提出的用以替代基本认证的方案

1.密码不再明文传递,而是用摘要来代替,一般使用MD5加密(基本不可逆,除非太简单)生成,服务端只存储摘要与客户端发来的摘要对比。

2.防止重放攻击,服务端向客户端发送随机数nonce,客户端生成摘要时得把nonce放在密码上,服务端知道用户的原始密码及nonce,接收到请求后再临时生成摘要与之对比

  1. 通过客户端产生随机数cnonce的方式,支持客户端对服务器的认证。

4.通过对内容也加入摘要计算的方式,可有选择的防止对报文内容的篡改。

摘要认证过程:

1.服务端接受客户端请求,生成随机数nonce,放在响应头WWW-Authenticate,状态码为401 Unauthorized

2.客户端发现是401,弹出让用户输入用户名密码的认证窗口,用户输入后生成摘要,放入请求头中的Authorization,

如果此时客户端也要对服务端进行认证,可生成并发送客户端随机数cnonce

3.服务端基于用户原始密码及nonce重新生成摘要与客户端发来的摘要对比,如果客户端反过来用客户端随机数对服务器进行质询,就会创建客户端摘要。

服务器可以预先将下一个随机数计算出来,提前将其传递给客户端,这样下一次客户端就可以预先发送正确的摘要了。

表单认证

表单验证,就是提交数据时对数据进行验证是否符合要求规则
表单认证是javascript中的高级选项之一。JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证。

表单验证的作用:

下面的函数用来检查用户是否已填写表单中的必填(或必选)项目。假如必填或必选项为空,那么警告框会弹出,并且函数的返回值为 false,否则函数的返回值则为 true(意味着数据没有问题):
function validate_required(field, alerttxt)
{ with(field)
{ if (value == null || value == "")
{ alert(alerttxt); return false; }
else { return true; } } }
下面是连同 HTML 表单的代码:

<html>
<head>
    <script type="text/javascript"> 
        function validate_required(field, alerttxt) { 
            with(field) { 
                if (value == null || value == "") { 
                    alert(alerttxt); return false; 
                } else { 
                    return true; 
                } 
            } 
        } 
        function validate_form(thisform) { 
            with(thisform) { 
                if (validate_required(email, "Email must be filled out!") == false) { 
                    email.focus(); return false; 
                } 
            } 
        } 
    </script> 
</head> 
<body> 
<form action="submitpage.htm" onsubmit="return validate_form(this)" method="post"> 
    Email: 
    <input type="text" name="email" size="30"> 
    <input type="submit" value="Submit"> 
</form> 
</body> 
</html>

相关文章

网友评论

      本文标题:认证

      本文链接:https://www.haomeiwen.com/subject/rwoslqtx.html