天天看点

客户端和服务端鉴权认证

鉴权是指验证用户访问系统的权力

session-cookie方式:

每当请求到达服务器端的时候,先去查一下该客户端有没有在服务器端创建seesion,如果有则已经认证成功了,否则就没有认证。

session-cookie认证主要分四步:

  1. 服务器在接受客户端首次访问时在服务器端创建seesion,然后保存seesion(我们可以将seesion保存在内存中,也可以保存在redis中,推荐使用后者),然后给这个session生成一个唯一的标识字符串,然后在响应头中种下这个唯一标识字符串。
  2. 签名。这一步只是对sid进行加密处理,服务端会根据这个secret密钥进行解密。(非必需步骤)
  3. 浏览器中收到请求响应的时候会解析响应头,然后将sid保存在本地cookie中,浏览器在下次http请求de 请求头中会带上该域名下的cookie信息
  4. 服务器在接受客户端请求时会去解析请求头cookie中的sid,然后根据这个sid去找服务器端保存的该客户端的session,然后判断该请求是否合法。

Token 方式:

使用基于 Token 的身份验证方法

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

总的来说就是客户端在首次登陆以后,服务端再次接收http请求的时候,就只认token了,请求只要每次把token带上就行了,服务器端会拦截所有的请求,然后校验token的合法性,合法就放行,不合法就返回401(鉴权失败)。

乍的一看好像和前面的seesion-cookie有点像,seesion-cookie是通过seesionid来作为浏览器和服务端的链接桥梁,而token验证方式貌似是token来起到seesionid的角色。其实这两者差别是很大的。

  1. sessionid 他只是一个唯一标识的字符串,服务端是根据这个字符串,来查询在服务器端保持的seesion,这里面才保存着用户的登陆状态。但是token本身就是一种登陆成功凭证,他是在登陆成功后根据某种规则生成的一种信息凭证,他里面本身就保存着用户的登陆状态。服务器端只需要根据定义的规则校验这个token是否合法就行。
  2. session-cookie是需要cookie配合的,居然要cookie,那么在http代理客户端的选择上就是只有浏览器了,因为只有浏览器才会去解析请求响应头里面的cookie,然后每次请求再默认带上该域名下的cookie。但是我们知道http代理客户端不只有浏览器,还有原生APP等等,这个时候cookie是不起作用的,或者浏览器端是可以禁止cookie的(虽然可以,但是这基本上是属于吃饱没事干的人干的事)…,但是token 就不一样,他是登陆请求在登陆成功后再请求响应体中返回的信息,客户端在收到响应的时候,可以把他存在本地的cookie,storage,或者内存中,然后再下一次请求的请求头重带上这个token就行了。简单点来说cookie-session机制他限制了客户端的类型,而token验证机制丰富了客户端类型。
  3. 时效性。session-cookie的sessionid实在登陆的时候生成的而且在登出事时一直不变的,在一定程度上安全就会低,而token是可以在一段时间内动态改变的。
  4. 可扩展性。token验证本身是比较灵活的,一是token的解决方案有许多,常用的是JWT,二来我们可以基于token验证机制,专门做一个鉴权服务,用它向多个服务的请求进行统一鉴权。

OAuth(开放授权):

OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容,为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。我们常见的提供OAuth认证服务的厂商有支付宝,QQ,微信。

OAuth协议又有1.0和2.0两个版本。相比较1.0版,2.0版整个授权验证流程更简单更安全,也是目前最主要的用户身份验证和授权方式。

以csdn登陆为例

  1. 向用户请求授权,现在很多的网站在登陆的时候都有第三方登陆的入口,当我们点击等第三方入口时,第三方授权服务会引导我们进入第三方登陆授权页面。
客户端和服务端鉴权认证
https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=100270989&redirect_uri=https://passport.csdn.net/account/login?oauth_provider=QQProvider&state=test

Auth2.0常见的几个请求参数:

response_type,返回类型

client_id,应用id,由授权服务器(qq)在应用提交时颁发给应用。

redirect_uri,登陆成功重定向页面

oauth_provider,授权提供方

state,由应用给出的随机码

  1. 返回用户凭证(code),并返回一个凭证(code),当用户点击授权并登陆后,授权服务器将生成一个用户凭证(code)。这个用户凭证会附加在重定向的地址redirect_uri的后面
https://passport.csdn.net/account/login?code=9e3efa6cea739f9aaab2&state=XXX
  1. 经过第二部获取code后,后面的工作就可以交给应用后台去处理了,和用户的交互就结束了。接下来我的需要获取Access Token,我们需要用他来向授权服务器获取用户信息等资源。

    应用后台通过第二步的凭证(code)向授权服务器请求Access Token,这时候需要以下几个信息:

    client_id 标识应用的id,由授权服务器(Github)在应用提交时颁发给应用

    client_secret 应用和授权服务器之间的安全凭证,由授权服务器(Github)在应用提交时颁发给应用

    code 第一步中返回的用户凭证redirect_uri 第一步生成用户凭证后跳转到第二步时的地址

    state 由应用给出的随机码

  2. 授权服务器同意授权后,返回一个资源访问的凭证(Access Token)。
  3. 应用通过第四步的凭证(Access Token)向资源服务器请求相关资源
  4. 资源服务器验证凭证(Access Token)通过后,将该应用请求的资源返回。