几种常见的前后端认证方法(综述)
最近我们重构了公司之前产品的前端代码,放弃了之前的session-cookie认证方式,采用了令牌认证。在我忙碌的时候,我觉得有必要整理几种常见的认证方法。
目前常用的认证有四种:
HTTP基本认证会话-cookie令牌认证OAuth (oauth2.0) i. http基本认证
这种授权模式是浏览器遵守http协议的基本授权模式。在HTTP协议通信过程中,HTTP协议定义了基本认证允许HTTP服务器为客户端进行用户身份证的方法。
身份验证过程:
1.客户端向服务器请求数据,请求的内容可以是网页或ajax异步请求。此时,假设客户端尚未被认证,客户端向服务器:提供以下请求
Host:www.google.com
2.服务器向客户端发送认证请求代码401。(www-authenticate : basic realm=" Google.com "是关键。如果没有客户端,则不会弹出用户名和密码输入界面。)服务器返回的数据一般如下:
HTTP/1.0 401 unauthorized server : SokEvo/1.0 WWW-authenticate : Basic realm=" Google.com " Content-type : text/html Content-length : XXX
3.当满足http1.0或1.1规范的客户端(如IE和FIREFOX)收到返回值401时,会自动弹出登录窗口,要求用户输入用户名和密码。
4.用户输入用户名和密码后,通过BASE64加密对用户名和密码进行加密,并将密文放入之前的请求消息中,那么客户端发送的第一条请求消息就变成了如下:
get/index . html HTTP/1.0 Host:www.google.com授权:基本d2FuZzp3YW5n
注意:d2FuZzp3YW5n代表加密后的用户名和密码(用户名:password然后用base64加密,加密过程是浏览器的默认行为,所以我们不需要人工加密,只需要输入用户名和密码即可)
5.服务器收到上述请求信息后,取出授权字段后的用户信息进行解密,并将解密后的用户名和密码与用户数据库进行比对验证。如果用户名和密码正确,服务器将根据请求向客户端发送请求的资源。
效果:
当客户端未通过身份验证时,将弹出用户名和密码输入框。此时,请求处于待定状态。此时,当用户输入用户名和密码时,客户端将再次发送带有身份验证头的请求。
身份验证成功:
server.js
let express=require(' express ');let app=express();app . use(express . static(_ _ dirname '/public ');app.get('/Authentication_base ',函数(req,RES){ console . log(' req . headers . authorization : ',req.headers) if(!req . headers . authorization){ RES . set({ ' WWW-Authenticate ' : ' Basic realm=' Wang ' ' });第401号决议。end();} else { let base64=req . headers . authorization . split(')[1];让userPass=新缓冲区(base64,' base64 ')。toString()。拆分(' : ');让用户=user pass[0];let pass=user pass[1];if(user==' Wang ' pass=' Wang '){ RES . end(' OK ');}else{ res.status(401)。end();} } })app . listen(9090)index . html :
!DOCTYPE html html head meta charset=' UTF-8 ' title http基本身份验证/title /head body div/div脚本src=' http : js/jquery-3 . 2 . 1 . js '/脚本脚本$(function(){ send('。/Authentication _ base’);}) var send=function(url){ $。ajax({ url : url,方法: 'GET ',});}/script/body/HTMl当然,我们登录的时候会有注销。我们会发现,当我们成功进行身份验证时,请求头会带来Authentication及其内容,那么如何才能使这个登录无效呢?
在网上搜索了很久之后,目前最有效的方法就是在注销操作的时候,在服务器上设置一个专门的注销账号。当收到的身份验证信息是注销用户名和密码时,登录成功。当客户端注销时,它会手动修改最需要注意的身份验证,并设置不是服务器默认值的注销帐户和密码。
通过上面简单的解释,其实我们可以把这种认证方式的缺陷退回来。加密方法简单,只有base64加密,而且这种加密方法是可逆的。同时,用户名和密码信息将附加在每个请求的报头中,以便外部网络中的嗅探器可以轻松检测到。
摘要:
形式上,正因为如此,这种加密方式一般用于内部安全要求较低的系统,但相对较多。一般来说,现在很少使用这种认证方式。如果项目需要部署在公共网络上,不建议使用这种方法。当然,你可以用SSL加密传输,这样会更好。如果我以后有时间研究这个。
二.会话cookie
第二种方式是利用服务器端的会话和浏览器端的cookie来实现前端和后端的认证。由于http请求是无状态的,服务器通常不知道当前的请求之前是否已经发出过。此时,如果我们想要记录状态,我们需要在服务器端创建一个会话来维护同一个客户端在自己的会话中的请求。每当请求到达服务器时,首先检查客户端是否在服务器上创建了seesion。如果是,则已成功认证;否则,它尚未通过身份验证。会话cookie认证主要分为四个步骤:1 .当服务器接收到来自客户端的第一次访问时,它会在服务器端创建一个seesion,然后保存seesion(我们可以将seesion保存在内存或redis中,建议使用后者),然后为这个会话生成一个唯一的标识字符串,然后将这个唯一的标识字符串植入响应头中。2.签名。这一步只加密sid,服务器会根据这个密钥解密。(可选步骤)3。当浏览器收到请求响应时,它将解析响应头,然后将sid保存在本地cookie中。浏览器将把cookie信息放在下一个http请求报头的域名下。4.当服务器接受客户端请求时,会解析请求头cookie中的sid,然后根据sid找到服务器保存的客户端的会话,进而判断请求是否合法。
server . js(nodejs express seesion redis)
var express=require(' express ');var redis store=require(' connect-redis ')(express . session);var app=express();var secret=' Wang 839305939 '/set cookieapp。使用(快递。cookie解析器(秘密));//set session app . use(express . session({ store : new redis store({ host 3360 ' 127 . 0 . 0 . 1 '、port: 6379、db:' session _ db'})、secret 3360 secret })app . get('/'、function(req,RES){ var session=req . session;session . time=session . time | | 0;var n=session.timeres.send('hello,session id : ' session . id ' count : ' n);});app . listen(9080);三.令牌验证
使用基于令牌的自动身份验证方法,大致过程如下:
1.客户端请求使用用户名和密码登录。2.服务器接收验证用户名和密码的请求。3.验证成功后,服务器将颁发一个Token并将其发送给客户端。4.客户端可以在收到令牌后存储它。例如,将其放在Cookie或本地存储中。5.每次客户端向服务器请求资源时,都需要携带服务器颁发的令牌。6.服务器接收请求,然后验证客户端请求中携带的令牌。如果验证成功,将请求的数据返回给客户端。
一般来说,当客户端第一次登录,服务器再次收到http请求时,它只识别token,请求只需要每次都带token。服务器会拦截所有请求,然后验证令牌的合法性,如果合法就释放,如果非法就返回401(认证失败)。
乍一看,它似乎有点像以前的see-cookie。seesion-cookie通过seesionid充当浏览器和服务器之间的链接桥梁,而令牌身份验证似乎是扮演seesionid角色的令牌。其实两者的区别很大。1.sessionid只是一个唯一的标识字符串,服务器根据这个字符串查询保存在服务器端的seesion,只保存用户的登录状态。但是,token本身是成功登录凭证,是成功登录后按照一定规则生成的信息凭证,它本身存储了用户的登录状态。服务器只需要根据定义的规则检查令牌是否合法。2.session-cookie需要cookie来配合它。如果需要cookie,浏览器是http代理客户端的唯一选择,因为只有浏览器会解析请求响应头中的cookie,然后默认情况下每个请求都会在域名下带来cookie。但是我们知道http代理客户端不仅仅是浏览器,还是原生APP等。这个时候,cookies不起作用,或者浏览器可以禁止cookies(虽然有可能,但基本属于吃饱了没事干的人).但令牌不同。它在登录请求成功后请求响应主体返回的信息。当客户端收到响应时,您可以将其存储在本地cookie、存储或内存中,然后将此令牌带到下一个请求的请求头。简单来说,cookie-session机制限制了客户端的类型,而令牌认证机制丰富了客户端的类型。3.及时性。Session-cookie的sessionid实际上是登录时生成的,注销时保持不变,所以安全性会有一定程度的降低,而token可以在一段时间内动态改变。4.可扩展性。令牌认证本身是灵活的。首先,代币的解决方案很多,常用的是JWT。第二,我们可以专门研究基于令牌认证机制的认证服务,并使用它来统一认证来自多个服务的请求。
让我们以最常用的JWT(JSON网络令牌)为例:
JWT是Auth0提出的一种通过加密json实现授权验证的方案,即登录成功后,将相关信息组成JSON对象,然后将这个对象以一定的方式加密后返回给客户端。客户端将在下一个请求中携带此令牌,服务器将在再次接收请求时验证令牌的有效性,这实际上是在验证请求的有效性。JWT物体通常由三部分组成:
标题:包括类别(典型)和加密算法(alg)
{'alg' :' hs 256 ',' typ' :' jwt'}声明:包括要传输的用户信息
{'sub' :' 1234567890 ',' name' :' John Doe ',' admin' : true}签名:根据alg算法和私钥加密的签名字符串,是最重要的敏感信息,只能在服务器端解密;
hmacsha256编码的JWT(base64 URL encode(header)' . 'base64 urlencode (claims),secreate _ key)看起来像这样的字符串:
eyjhbgcioijiuzi 1 nisinr 5 CCI 6 ikpxvcj 9 . eyjzdwioiixmjm 0 nty 3 dkwiiwibmftzsi 6 ikpvag4grg 9 . tjva 95 ORM 7 e2cbab 30 rmhrhdcefjoyzgefonfh7 hgq
nodejs express jwt-简单
auth.js
让jwt=require(' jwt-simple ');let secret=' wangyy让时间=10;module.exports={/* *验证令牌*/validate:function (req,RES,next)的有效性{ let token=req . body . token | | req . headers[' xsstoken '];if(token){ let decodoken=null;尝试{//防止假令牌解析和报告错误。decadetoken=jwt . decode(token,secret,' hs 256 ');} catch (err) {res.status (401)。发送(“非法访问”);返回;}让exp=decodeToken.expif(!{ res.status(401)。发送(“非法访问”);}让现在=新日期()。getTime();if(exp(now time * 60 * 1000)){ RES . send({ code : ' 002 ',' errormsg' : '授权超时' })} next();}else{ res.status(401)。发送(“非法访问”);}},/*生成标记*/make token(){让标记=null让有效负载={ time:new Date()。getTime(),exp : this . makexp(time)} Token=jwt . encode(有效负载,秘密,HS256)返回Token;},/*生成令牌到期时间*/makeexp:函数(time){ let stamp=time 601000;} }server.js
let express=require(' express ');let app=express();让body parser=require(' body-parser ');let auth=require('。/lib/auth . js ');让粉笔=require('粉笔');app . use(BodyParser . JSON());app.post('/login ',函数(req,res,next){ let Token=auth . make Token();res.json({result:'success ',token:Token},200)});app.use('* ',[auth.validate],函数(req,res,next){ RES . send(' success ');});App.listen('9999 ')只是一个简单的令牌生成和验证。如果需要,可以根据实际需要进行逻辑处理
四.OAuth (oauth2.0)
OAuth (oauth2.0)是一个开放标准,它允许用户授权第三方网站访问存储在其他服务提供商中的信息,而无需向第三方网站提供用户名和密码,也无需共享其数据的所有内容。为了保护用户数据的安全和隐私,第三方网站在访问用户数据之前需要明确要求用户授权。我们常见的OAuth认证服务提供商有支付宝、QQ、微信。OAuth协议有两个版本:1.0和2.0。与1.0版本相比,2.0版本的整个授权验证过程更简单、更安全,也是目前最重要的用户认证和授权方式。
以下是auth2.0的流程图:
从图中我们可以看到,auth2.0流程分为六层(我们将以csdn登录为例):
第一步:要求用户授权。现在很多网站在登录的时候都有第三方登录入口。当我们点击第三方入口时,第三方授权服务会引导我们进入第三方登录授权页面。
从第三方请求授权页面的浏览器地址栏地址可以看出,
https://graph.qq.com/oauth2.0/show?哪个=Logindisplay=PC response _ type=code client _ id=100270989 redirect _ uri=https://passport . csdn . net/account/log in?oauth _ provider=QQProviderstate=test
此处地址中的%是浏览器强制编码后的显示。我们可以使用decodeURIComponent对其进行解码。解码后,是这样的:
https://graph.qq.com/oauth2.0/show?哪个=Logindisplay=PC response _ type=code client _ id=100270989 redirect _ uri=https://passport . csdn . net/account/log in?oauth _ provider=QQProviderstate=test
在这个url地址,我们可以看到Auth2.0的几个常见参数:response_type、return type client_id和第三方应用程序id,这些参数是在第三方应用程序提交时由授权服务器(qq)颁发给第三方应用程序的。Redirect_uri,登录成功重定向页面oauth_provider,第三方授权提供者状态,第三方应用给出的随机代码第二步:返回用户证书(代码),返回一个证书(代码)。当用户点击授权并登录时,授权服务器将生成一个用户证书(代码)。此用户凭据将被附加到重定向地址重定向uri
https://passport.csdn.net/account/login?代码=9e3ef a6 CEA 739 F9 aab2state=XXX
第三步。向授权服务器:请求授权
获得第二部分的代码后,接下来的工作就可以交给后台处理了,与用户的交互也就结束了。接下来,我需要获取Access Token,我们需要使用它从授权服务器获取用户信息和其他资源。第三方应用程序后台通过第二步中的代码从授权服务器请求访问令牌,这需要以下信息:
Client_id标识第三方应用程序的id,在第三方应用程序提交时,由Github颁发给第三方应用程序client_secret。由第三方应用程序提交时,由Github颁发给第三方应用程序代码。步骤1中返回的redirect_uri。生成用户证书后,跳转到步骤2中的地址状态。第三方应用程序给出的随机代码。第四步。授权后,授权服务器返回一个访问令牌。
步骤5:第三方应用程序通过步骤4中的访问令牌向资源服务器请求相关资源。
第六步:资源服务器通过访问令牌后,返回第三方应用请求的资源。
从用户的角度来看,第三方授权让我们可以快速登录应用,不需要繁琐的注册,也不需要记住各种账号密码。只要记住你平时的账目,你就会没事的。从产品经理的角度来看,这种授权方式可以提高用户的体验满意度。另一方面,可以获得更多的用户。
总结:
授权的方式很多,主要看我们对产品的定位。如果我们的产品只用于企业,令牌和会话可以满足我们的需求。如果我们的产品是面向互联网用户的,那么第三方授权会大大提升用户体验。
再次,上面可能有很多“通假字”。别怪我。我写作的目的,一方面是想和大家分享我所掌握的所有点滴,另一方面是整理我所掌握的知识。
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:几种常见的前后端认证方法(综述)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。